mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-06 03:50:02 +02:00
GT-3112 - PDB Universal - review changes
This commit is contained in:
parent
a1d7ed2cb2
commit
9f7fc60f76
65 changed files with 1046 additions and 1045 deletions
|
@ -51,9 +51,10 @@ import ghidra.util.task.TaskMonitor;
|
|||
|
||||
/**
|
||||
* PDB Universal Reader/Analyzer. Uses raw PDB files (not XML-converted PDBs). Attempts to
|
||||
* apply the information to a program.
|
||||
* apply the information to a program. It has Universal in the name to describe the fact that
|
||||
* it written in java, making it platform independent, unlike a previous PDB analyzer.
|
||||
*/
|
||||
public class Pdb2Analyzer extends AbstractAnalyzer {
|
||||
public class PdbUniversalAnalyzer extends AbstractAnalyzer {
|
||||
|
||||
// Developer turn on/off options that are in still in development.
|
||||
private static final boolean developerMode = false;
|
||||
|
@ -211,7 +212,7 @@ public class Pdb2Analyzer extends AbstractAnalyzer {
|
|||
|
||||
//==============================================================================================
|
||||
//==============================================================================================
|
||||
public Pdb2Analyzer() {
|
||||
public PdbUniversalAnalyzer() {
|
||||
super(NAME, DESCRIPTION, AnalyzerType.BYTE_ANALYZER);
|
||||
setPrototype();
|
||||
// false for now; after proven... then TODO: true always
|
|
@ -29,7 +29,7 @@ import ghidra.program.model.data.CategoryPath;
|
|||
* while parsing a PDB and the count (state) of anonymous functions for their creation within
|
||||
* the particular PDB's {@link Category}.
|
||||
*/
|
||||
public class PdbCategoryUtils {
|
||||
public class PdbCategories {
|
||||
|
||||
private CategoryPath pdbRootCategory;
|
||||
private CategoryPath pdbUncategorizedCategory;
|
||||
|
@ -49,7 +49,7 @@ public class PdbCategoryUtils {
|
|||
* @param pdbCategoryName pathname of the PDB file that this category represents.
|
||||
* @param moduleNames module names
|
||||
*/
|
||||
public PdbCategoryUtils(String pdbCategoryName, List<String> moduleNames) {
|
||||
public PdbCategories(String pdbCategoryName, List<String> moduleNames) {
|
||||
Objects.requireNonNull(pdbCategoryName, "pdbCategoryName cannot be null");
|
||||
|
||||
pdbRootCategory = new CategoryPath(CategoryPath.ROOT, pdbCategoryName);
|
|
@ -85,6 +85,10 @@ public class PdbNamespaceUtils {
|
|||
* @param index the index number used be used as part of a unique tag name.
|
||||
* @return the resulting name.
|
||||
*/
|
||||
// TODO: investigate if we can work a solution that no longer needs/has the index attached.
|
||||
// I don't believe we are handling all of these correctly... someone else suggests regex, but
|
||||
// that makes work in this area less clear until we know what we are doing...
|
||||
// so, for now... DO NOT DO REGEX.
|
||||
public static String fixUnnamed(String name, int index) {
|
||||
if ("<unnamed-tag>".equals(name)) {
|
||||
return String.format("<unnamed-tag_%08X>", index);
|
||||
|
|
|
@ -19,17 +19,20 @@ import ghidra.app.util.SymbolPath;
|
|||
import ghidra.app.util.SymbolPathParser;
|
||||
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.app.util.bin.format.pdb2.pdbreader.type.AbstractComplexMsType;
|
||||
import ghidra.app.util.pdb.PdbNamespaceUtils;
|
||||
import ghidra.program.model.data.DataType;
|
||||
|
||||
public abstract class AbstractComplexTypeApplier extends AbstractMsTypeApplier {
|
||||
/**
|
||||
* Applier for {@link AbstractComplexMsType} types.
|
||||
*/
|
||||
public abstract class AbstractComplexTypeApplier extends MsTypeApplier {
|
||||
|
||||
protected SymbolPath symbolPath;
|
||||
protected SymbolPath fixedSymbolPath;
|
||||
|
||||
protected AbstractComplexTypeApplier definitionApplier = null;
|
||||
protected AbstractComplexTypeApplier fwdRefApplier = null;
|
||||
protected AbstractComplexTypeApplier forwardReferenceApplier = null;
|
||||
|
||||
public static AbstractComplexTypeApplier getComplexApplier(PdbApplicator applicator,
|
||||
RecordNumber recordNumber) throws PdbException {
|
||||
|
@ -40,40 +43,31 @@ public abstract class AbstractComplexTypeApplier extends AbstractMsTypeApplier {
|
|||
/**
|
||||
* Constructor for complex type applier.
|
||||
* @param applicator {@link PdbApplicator} for which this class is working.
|
||||
* @param msType {@link AbstractEnumMsType} to process.
|
||||
* @throws IllegalArgumentException Upon invalid arguments.
|
||||
* @param msType {@link AbstractComplexMsType} to process.
|
||||
*/
|
||||
public AbstractComplexTypeApplier(PdbApplicator applicator, AbstractMsType msType)
|
||||
throws IllegalArgumentException {
|
||||
public AbstractComplexTypeApplier(PdbApplicator applicator, AbstractComplexMsType msType) {
|
||||
super(applicator, msType);
|
||||
String fullPathName = msType.getName();
|
||||
symbolPath = new SymbolPath(SymbolPathParser.parse(fullPathName));
|
||||
}
|
||||
|
||||
public SymbolPath getSymbolPath() {
|
||||
SymbolPath getSymbolPath() {
|
||||
return symbolPath;
|
||||
}
|
||||
|
||||
public boolean isForwardReference() {
|
||||
boolean isForwardReference() {
|
||||
return ((AbstractComplexMsType) msType).getMsProperty().isForwardReference();
|
||||
}
|
||||
|
||||
public boolean isFinal() {
|
||||
boolean isFinal() {
|
||||
return ((AbstractComplexMsType) msType).getMsProperty().isSealed();
|
||||
}
|
||||
|
||||
public void setFwdRefApplier(AbstractComplexTypeApplier fwdRefApplier) {
|
||||
this.fwdRefApplier = fwdRefApplier;
|
||||
void setForwardReferenceApplier(AbstractComplexTypeApplier forwardReferenceApplier) {
|
||||
this.forwardReferenceApplier = forwardReferenceApplier;
|
||||
}
|
||||
|
||||
<T extends AbstractComplexTypeApplier> T getFwdRefApplier(Class<T> typeClass) {
|
||||
if (!typeClass.isInstance(fwdRefApplier)) {
|
||||
return null;
|
||||
}
|
||||
return typeClass.cast(fwdRefApplier);
|
||||
}
|
||||
|
||||
public void setDefinitionApplier(AbstractComplexTypeApplier definitionApplier) {
|
||||
void setDefinitionApplier(AbstractComplexTypeApplier definitionApplier) {
|
||||
this.definitionApplier = definitionApplier;
|
||||
}
|
||||
|
||||
|
@ -84,6 +78,13 @@ public abstract class AbstractComplexTypeApplier extends AbstractMsTypeApplier {
|
|||
return typeClass.cast(definitionApplier);
|
||||
}
|
||||
|
||||
protected AbstractComplexTypeApplier getAlternativeTypeApplier() {
|
||||
if (isForwardReference()) {
|
||||
return definitionApplier;
|
||||
}
|
||||
return forwardReferenceApplier;
|
||||
}
|
||||
|
||||
protected SymbolPath getFixedSymbolPath() { //return mine or my def's (and set mine)
|
||||
if (fixedSymbolPath != null) {
|
||||
return fixedSymbolPath;
|
||||
|
|
|
@ -25,26 +25,22 @@ import ghidra.util.exception.CancelledException;
|
|||
/**
|
||||
* Applier for certain function types.
|
||||
*/
|
||||
public abstract class AbstractFunctionTypeApplier extends AbstractMsTypeApplier {
|
||||
|
||||
private boolean isDeferred = false;
|
||||
public abstract class AbstractFunctionTypeApplier extends MsTypeApplier {
|
||||
|
||||
private FunctionDefinitionDataType functionDefinition;
|
||||
|
||||
private AbstractMsTypeApplier returnApplier;
|
||||
private MsTypeApplier returnApplier;
|
||||
ArgumentsListTypeApplier argsListApplier;
|
||||
CallingConvention callingConvention;
|
||||
boolean hasThisPointer;
|
||||
|
||||
/**
|
||||
* Constructor for the applicator that applies a "function" type, transforming it into a
|
||||
* Ghidra DataType.
|
||||
* Ghidra DataType.
|
||||
* @param applicator {@link PdbApplicator} for which this class is working.
|
||||
* @param msType {@link AbstractMsType} to processes
|
||||
* @throws IllegalArgumentException Upon invalid arguments.
|
||||
*/
|
||||
public AbstractFunctionTypeApplier(PdbApplicator applicator, AbstractMsType msType)
|
||||
throws IllegalArgumentException {
|
||||
public AbstractFunctionTypeApplier(PdbApplicator applicator, AbstractMsType msType) {
|
||||
super(applicator, msType);
|
||||
String funcName = applicator.getNextAnonymousFunctionName();
|
||||
functionDefinition = new FunctionDefinitionDataType(
|
||||
|
@ -56,15 +52,6 @@ public abstract class AbstractFunctionTypeApplier extends AbstractMsTypeApplier
|
|||
}
|
||||
|
||||
//==============================================================================================
|
||||
public void setDeferred() {
|
||||
isDeferred = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDeferred() {
|
||||
return isDeferred;
|
||||
}
|
||||
|
||||
@Override
|
||||
void deferredApply() throws PdbException, CancelledException {
|
||||
if (isDeferred()) {
|
||||
|
@ -77,7 +64,7 @@ public abstract class AbstractFunctionTypeApplier extends AbstractMsTypeApplier
|
|||
* Returns the function definition being created by this applier.
|
||||
* @return the function definition.
|
||||
*/
|
||||
public FunctionDefinitionDataType getFunctionDefinition() {
|
||||
FunctionDefinitionDataType getFunctionDefinition() {
|
||||
return functionDefinition;
|
||||
}
|
||||
|
||||
|
@ -89,31 +76,55 @@ public abstract class AbstractFunctionTypeApplier extends AbstractMsTypeApplier
|
|||
return functionDefinition;
|
||||
}
|
||||
|
||||
AbstractMsTypeApplier getReturnTypeApplier() {
|
||||
/**
|
||||
* Returns the type applier of the return type
|
||||
* @return the type applier
|
||||
*/
|
||||
MsTypeApplier getReturnTypeApplier() {
|
||||
return applicator.getTypeApplier(getReturnRecordNumber());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link ArgumentsListTypeApplier}
|
||||
* @return the type applier
|
||||
*/
|
||||
ArgumentsListTypeApplier getArgsListApplier() {
|
||||
AbstractMsTypeApplier argsApplier = applicator.getTypeApplier(getArgListRecordNumber());
|
||||
MsTypeApplier argsApplier = applicator.getTypeApplier(getArgListRecordNumber());
|
||||
if (argsApplier instanceof ArgumentsListTypeApplier) {
|
||||
return (ArgumentsListTypeApplier) applicator.getTypeApplier(getArgListRecordNumber());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link CallingConvention}
|
||||
* @return the calling convention
|
||||
*/
|
||||
protected abstract CallingConvention getCallingConvention();
|
||||
|
||||
protected abstract boolean hasThisPointer() throws CancelledException, PdbException;
|
||||
/**
|
||||
* Returns whether the function has a "this" pointer
|
||||
* @return {@code true} if it has a "this" pointer
|
||||
*/
|
||||
protected abstract boolean hasThisPointer();
|
||||
|
||||
/**
|
||||
* Returns the {@link RecordNumber} of the function return type
|
||||
* @return the record number
|
||||
*/
|
||||
protected abstract RecordNumber getReturnRecordNumber();
|
||||
|
||||
/**
|
||||
* Returns the {@link RecordNumber} of the function arguments list
|
||||
* @return the record number
|
||||
*/
|
||||
protected abstract RecordNumber getArgListRecordNumber();
|
||||
|
||||
/**
|
||||
* Method to create the {@link DataType} based upon the type indices of the calling
|
||||
* convention, return type, and arguments list.
|
||||
* convention, return type, and arguments list.
|
||||
* @param callingConventionParam Identification of the {@link AbstractMsType} record of the
|
||||
* {@link CallingConvention}.
|
||||
* {@link CallingConvention}.
|
||||
* @param hasThisPointerParam true if has a this pointer
|
||||
* @return {@link DataType} created or null upon issue.
|
||||
* @throws PdbException when unexpected function internals are found.
|
||||
|
@ -169,7 +180,7 @@ public abstract class AbstractFunctionTypeApplier extends AbstractMsTypeApplier
|
|||
}
|
||||
}
|
||||
|
||||
public void applyInternal() throws CancelledException {
|
||||
private void applyInternal() throws CancelledException {
|
||||
if (isApplied()) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -22,26 +22,13 @@ import java.util.List;
|
|||
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.AbstractArgumentsListMsType;
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.type.AbstractMsType;
|
||||
import ghidra.program.model.data.*;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
|
||||
/**
|
||||
* Applier for {@link AbstractArgumentsListMsType} types.
|
||||
*/
|
||||
public class ArgumentsListTypeApplier extends AbstractMsTypeApplier {
|
||||
|
||||
private boolean isDeferred = false;
|
||||
|
||||
private static AbstractMsType validateType(AbstractMsType type)
|
||||
throws IllegalArgumentException {
|
||||
if (!(type instanceof AbstractArgumentsListMsType)) {
|
||||
throw new IllegalArgumentException(
|
||||
"PDB Incorrectly applying " + type.getClass().getSimpleName() + " to " +
|
||||
ArgumentsListTypeApplier.class.getSimpleName());
|
||||
}
|
||||
return type;
|
||||
}
|
||||
public class ArgumentsListTypeApplier extends MsTypeApplier {
|
||||
|
||||
/**
|
||||
* Constructor for the applicator that applies a arguments list.
|
||||
|
@ -49,21 +36,12 @@ public class ArgumentsListTypeApplier extends AbstractMsTypeApplier {
|
|||
* @param msType {@link AbstractArgumentsListMsType} to processes.
|
||||
* @throws IllegalArgumentException Upon invalid arguments.
|
||||
*/
|
||||
public ArgumentsListTypeApplier(PdbApplicator applicator, AbstractMsType msType)
|
||||
public ArgumentsListTypeApplier(PdbApplicator applicator, AbstractArgumentsListMsType msType)
|
||||
throws IllegalArgumentException {
|
||||
super(applicator, validateType(msType));
|
||||
super(applicator, msType);
|
||||
}
|
||||
|
||||
//==============================================================================================
|
||||
public void setDeferred() {
|
||||
isDeferred = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDeferred() {
|
||||
return isDeferred;
|
||||
}
|
||||
|
||||
@Override
|
||||
void deferredApply() throws PdbException, CancelledException {
|
||||
// Do nothing... Just need dependency tie of each argument to function.
|
||||
|
@ -72,13 +50,13 @@ public class ArgumentsListTypeApplier extends AbstractMsTypeApplier {
|
|||
//==============================================================================================
|
||||
// TODO: would be nice if we did not have to implement this method. Want the applyTo() below.
|
||||
@Override
|
||||
public void apply() throws PdbException, CancelledException {
|
||||
void apply() throws PdbException, CancelledException {
|
||||
// addMyDependenciesOnly();
|
||||
// // Silently do nothing.
|
||||
}
|
||||
|
||||
@Override
|
||||
public BigInteger getSize() {
|
||||
BigInteger getSize() {
|
||||
return BigInteger.ZERO;
|
||||
}
|
||||
|
||||
|
@ -104,13 +82,13 @@ public class ArgumentsListTypeApplier extends AbstractMsTypeApplier {
|
|||
// }
|
||||
// }
|
||||
//
|
||||
public void checkForDependencies(AbstractFunctionTypeApplier functionApplier)
|
||||
void checkForDependencies(AbstractFunctionTypeApplier functionApplier)
|
||||
throws CancelledException {
|
||||
AbstractArgumentsListMsType argsList = (AbstractArgumentsListMsType) msType;
|
||||
List<RecordNumber> args = argsList.getArgRecordNumbers();
|
||||
for (RecordNumber arg : args) {
|
||||
applicator.checkCanceled();
|
||||
AbstractMsTypeApplier argApplier = applicator.getTypeApplier(arg);
|
||||
MsTypeApplier argApplier = applicator.getTypeApplier(arg);
|
||||
|
||||
if (argApplier instanceof PrimitiveTypeApplier &&
|
||||
((PrimitiveTypeApplier) argApplier).isNoType()) {
|
||||
|
@ -137,7 +115,7 @@ public class ArgumentsListTypeApplier extends AbstractMsTypeApplier {
|
|||
* arguments.
|
||||
* @throws CancelledException Upon user cancellation
|
||||
*/
|
||||
public void applyTo(AbstractFunctionTypeApplier functionApplier) throws CancelledException {
|
||||
void applyTo(AbstractFunctionTypeApplier functionApplier) throws CancelledException {
|
||||
FunctionDefinitionDataType functionDefinition = functionApplier.getFunctionDefinition();
|
||||
|
||||
AbstractArgumentsListMsType argsList = (AbstractArgumentsListMsType) msType;
|
||||
|
@ -146,7 +124,7 @@ public class ArgumentsListTypeApplier extends AbstractMsTypeApplier {
|
|||
int parameterCount = 0;
|
||||
for (RecordNumber arg : args) {
|
||||
applicator.checkCanceled();
|
||||
AbstractMsTypeApplier argApplier = applicator.getTypeApplier(arg);
|
||||
MsTypeApplier argApplier = applicator.getTypeApplier(arg);
|
||||
|
||||
if (argApplier instanceof PrimitiveTypeApplier &&
|
||||
((PrimitiveTypeApplier) argApplier).isNoType()) {
|
||||
|
|
|
@ -19,7 +19,6 @@ import java.math.BigInteger;
|
|||
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.PdbException;
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.type.AbstractArrayMsType;
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.type.AbstractMsType;
|
||||
import ghidra.program.model.data.*;
|
||||
import ghidra.util.Msg;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
|
@ -27,45 +26,23 @@ import ghidra.util.exception.CancelledException;
|
|||
/**
|
||||
* Applier for {@link AbstractArrayMsType} types.
|
||||
*/
|
||||
public class ArrayTypeApplier extends AbstractMsTypeApplier {
|
||||
public class ArrayTypeApplier extends MsTypeApplier {
|
||||
|
||||
private boolean isDeferred = false;
|
||||
|
||||
private AbstractMsTypeApplier underlyingTypeApplier = null;
|
||||
private MsTypeApplier underlyingTypeApplier = null;
|
||||
private boolean isFlexibleArray = false;
|
||||
|
||||
private static AbstractMsType validateType(AbstractMsType type)
|
||||
throws IllegalArgumentException {
|
||||
if (!(type instanceof AbstractArrayMsType)) {
|
||||
throw new IllegalArgumentException("PDB Incorrectly applying " +
|
||||
type.getClass().getSimpleName() + " to " + ArrayTypeApplier.class.getSimpleName());
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for the applicator that applies a "array" type, transforming it into a
|
||||
* Ghidra DataType.
|
||||
* Ghidra DataType.
|
||||
* @param applicator {@link PdbApplicator} for which this class is working.
|
||||
* @param msType {@link AbstractArrayMsType} to processes.
|
||||
* @throws IllegalArgumentException Upon invalid arguments.
|
||||
*/
|
||||
public ArrayTypeApplier(PdbApplicator applicator, AbstractMsType msType)
|
||||
throws IllegalArgumentException {
|
||||
super(applicator, validateType(msType));
|
||||
public ArrayTypeApplier(PdbApplicator applicator, AbstractArrayMsType msType) {
|
||||
super(applicator, msType);
|
||||
}
|
||||
|
||||
//==============================================================================================
|
||||
public void setDeferred() {
|
||||
isDeferred = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDeferred() {
|
||||
return isDeferred;
|
||||
}
|
||||
|
||||
public boolean isFlexibleArray() {
|
||||
boolean isFlexibleArray() {
|
||||
return isFlexibleArray;
|
||||
}
|
||||
|
||||
|
@ -76,12 +53,12 @@ public class ArrayTypeApplier extends AbstractMsTypeApplier {
|
|||
|
||||
//==============================================================================================
|
||||
@Override
|
||||
public BigInteger getSize() {
|
||||
BigInteger getSize() {
|
||||
return ((AbstractArrayMsType) msType).getSize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply() throws PdbException, CancelledException {
|
||||
void apply() throws PdbException, CancelledException {
|
||||
applyOrDeferForDependencies();
|
||||
}
|
||||
|
||||
|
|
|
@ -24,9 +24,9 @@ import ghidra.util.exception.CancelledException;
|
|||
|
||||
/**
|
||||
* Applier for {@link AbstractBaseClassMsType}, {@link AbstractVirtualBaseClassMsType}, and
|
||||
* {@link AbstractIndirectVirtualBaseClassMsType} types.
|
||||
* {@link AbstractIndirectVirtualBaseClassMsType} types.
|
||||
*/
|
||||
public class BaseClassTypeApplier extends AbstractMsTypeApplier {
|
||||
public class BaseClassTypeApplier extends MsTypeApplier {
|
||||
|
||||
private static AbstractMsType validateType(AbstractMsType type)
|
||||
throws IllegalArgumentException {
|
||||
|
@ -57,7 +57,7 @@ public class BaseClassTypeApplier extends AbstractMsTypeApplier {
|
|||
// For here, we are only reporting what "we" have, not what the underlying sizes are.
|
||||
// ...and a value of zero is our "don't know" and "not represented" value.
|
||||
@Override
|
||||
public BigInteger getSize() {
|
||||
BigInteger getSize() {
|
||||
return BigInteger.ZERO;
|
||||
}
|
||||
|
||||
|
@ -66,7 +66,7 @@ public class BaseClassTypeApplier extends AbstractMsTypeApplier {
|
|||
* @return the offset.
|
||||
* @throws PdbException if field is not available.
|
||||
*/
|
||||
public BigInteger getOffset() throws PdbException {
|
||||
BigInteger getOffset() throws PdbException {
|
||||
if (msType instanceof AbstractBaseClassMsType) {
|
||||
return ((AbstractBaseClassMsType) msType).getOffset();
|
||||
}
|
||||
|
@ -78,7 +78,7 @@ public class BaseClassTypeApplier extends AbstractMsTypeApplier {
|
|||
* @return the offset.
|
||||
* @throws PdbException if field is not available.
|
||||
*/
|
||||
public BigInteger getBasePointerOffset() throws PdbException {
|
||||
BigInteger getBasePointerOffset() throws PdbException {
|
||||
if (msType instanceof AbstractBaseClassMsType) {
|
||||
throw new PdbException("Base Pointer Offset is not valid field");
|
||||
}
|
||||
|
@ -92,7 +92,7 @@ public class BaseClassTypeApplier extends AbstractMsTypeApplier {
|
|||
* Returns the attributes of the base class within the inheriting class.
|
||||
* @return the attributes;
|
||||
*/
|
||||
public ClassFieldMsAttributes getAttributes() {
|
||||
ClassFieldMsAttributes getAttributes() {
|
||||
if (msType instanceof AbstractBaseClassMsType) {
|
||||
return ((AbstractBaseClassMsType) msType).getAttributes();
|
||||
}
|
||||
|
@ -106,7 +106,7 @@ public class BaseClassTypeApplier extends AbstractMsTypeApplier {
|
|||
* Returns the record number of the base class.
|
||||
* @return the record number;
|
||||
*/
|
||||
public RecordNumber getBaseClassRecordNumber() {
|
||||
RecordNumber getBaseClassRecordNumber() {
|
||||
if (msType instanceof AbstractBaseClassMsType) {
|
||||
return ((AbstractBaseClassMsType) msType).getBaseClassRecordNumber();
|
||||
}
|
||||
|
@ -120,7 +120,7 @@ public class BaseClassTypeApplier extends AbstractMsTypeApplier {
|
|||
* Returns whether there is a Virtual Base Pointer type index available.
|
||||
* @return {@code true} if available.
|
||||
*/
|
||||
public boolean hasVirtualBasePointerTypeIndex() {
|
||||
boolean hasVirtualBasePointerTypeIndex() {
|
||||
return (!(msType instanceof AbstractBaseClassMsType));
|
||||
}
|
||||
|
||||
|
@ -129,7 +129,7 @@ public class BaseClassTypeApplier extends AbstractMsTypeApplier {
|
|||
* @return the record number;
|
||||
* @throws PdbException if not a virtual base class.
|
||||
*/
|
||||
public RecordNumber getVirtualBasePointerRecordNumber() throws PdbException {
|
||||
RecordNumber getVirtualBasePointerRecordNumber() throws PdbException {
|
||||
if (msType instanceof AbstractVirtualBaseClassMsType) {
|
||||
return ((AbstractVirtualBaseClassMsType) msType).getVirtualBasePointerRecordNumber();
|
||||
}
|
||||
|
@ -140,7 +140,7 @@ public class BaseClassTypeApplier extends AbstractMsTypeApplier {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void apply() throws PdbException, CancelledException {
|
||||
void apply() throws PdbException, CancelledException {
|
||||
// do nothing at the moment.
|
||||
}
|
||||
|
||||
|
|
|
@ -20,7 +20,6 @@ import java.math.BigInteger;
|
|||
import ghidra.app.util.bin.format.pdb.PdbBitField;
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.PdbException;
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.type.AbstractBitfieldMsType;
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.type.AbstractMsType;
|
||||
import ghidra.program.model.data.DataType;
|
||||
import ghidra.program.model.data.InvalidDataTypeException;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
|
@ -28,32 +27,20 @@ import ghidra.util.exception.CancelledException;
|
|||
/**
|
||||
* Applier for {@link AbstractBitfieldMsType} types.
|
||||
*/
|
||||
public class BitfieldTypeApplier extends AbstractMsTypeApplier {
|
||||
private AbstractMsTypeApplier elementTypeApplier = null;
|
||||
|
||||
private static AbstractMsType validateType(AbstractMsType type)
|
||||
throws IllegalArgumentException {
|
||||
if (!(type instanceof AbstractBitfieldMsType)) {
|
||||
throw new IllegalArgumentException(
|
||||
"PDB Incorrectly applying " + type.getClass().getSimpleName() + " to " +
|
||||
BitfieldTypeApplier.class.getSimpleName());
|
||||
}
|
||||
return type;
|
||||
}
|
||||
public class BitfieldTypeApplier extends MsTypeApplier {
|
||||
private MsTypeApplier elementTypeApplier = null;
|
||||
|
||||
/**
|
||||
* Constructor for bitfield applier.
|
||||
* @param applicator {@link PdbApplicator} for which this class is working.
|
||||
* @param msType {@link AbstractBitfieldMsType} to processes
|
||||
* @throws IllegalArgumentException Upon invalid arguments.
|
||||
*/
|
||||
public BitfieldTypeApplier(PdbApplicator applicator, AbstractMsType msType)
|
||||
throws IllegalArgumentException {
|
||||
super(applicator, validateType(msType));
|
||||
public BitfieldTypeApplier(PdbApplicator applicator, AbstractBitfieldMsType msType) {
|
||||
super(applicator, msType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BigInteger getSize() {
|
||||
BigInteger getSize() {
|
||||
if (elementTypeApplier == null) {
|
||||
return BigInteger.ZERO;
|
||||
}
|
||||
|
@ -61,7 +48,7 @@ public class BitfieldTypeApplier extends AbstractMsTypeApplier {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void apply() throws PdbException, CancelledException {
|
||||
void apply() throws PdbException, CancelledException {
|
||||
// The bitfield does not get resolved/commited to the DataTypeManager.
|
||||
dataType = applyBitfieldMsType((AbstractBitfieldMsType) msType);
|
||||
}
|
||||
|
@ -94,7 +81,7 @@ public class BitfieldTypeApplier extends AbstractMsTypeApplier {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void resolve() {
|
||||
void resolve() {
|
||||
// Do not resolve Bitfield Types... will be resolved with composite!!!
|
||||
}
|
||||
|
||||
|
|
|
@ -23,6 +23,9 @@ import ghidra.program.model.address.Address;
|
|||
import ghidra.program.model.listing.CodeUnit;
|
||||
import ghidra.program.model.listing.Program;
|
||||
|
||||
/**
|
||||
* Manages the nesting of scoping blocks for functions and scoped variables.
|
||||
*/
|
||||
public class BlockCommentsManager {
|
||||
|
||||
private static final String BLOCK_INDENT = " ";
|
||||
|
|
|
@ -16,22 +16,25 @@
|
|||
package ghidra.app.util.pdb.pdbapplicator;
|
||||
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.PdbException;
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.PdbLog;
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.symbol.AbstractBlockMsSymbol;
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.symbol.AbstractMsSymbol;
|
||||
import ghidra.app.util.pdb.pdbapplicator.SymbolGroup.AbstractMsSymbolIterator;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.util.Msg;
|
||||
import ghidra.util.exception.AssertException;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
|
||||
/**
|
||||
* Applier for {@link AbstractBlockMsSymbol} symbols.
|
||||
*/
|
||||
public class BlockSymbolApplier extends AbstractMsSymbolApplier {
|
||||
public class BlockSymbolApplier extends MsSymbolApplier {
|
||||
|
||||
private AbstractBlockMsSymbol symbol;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param applicator the {@link PdbApplicator} for which we are working.
|
||||
* @param iter the Iterator containing the symbol sequence being processed
|
||||
*/
|
||||
public BlockSymbolApplier(PdbApplicator applicator, AbstractMsSymbolIterator iter) {
|
||||
super(applicator, iter);
|
||||
AbstractMsSymbol abstractSymbol = iter.next();
|
||||
|
@ -43,22 +46,21 @@ public class BlockSymbolApplier extends AbstractMsSymbolApplier {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void apply() throws PdbException, CancelledException {
|
||||
String message = "Cannot apply " + this.getClass().getSimpleName() + " directly to program";
|
||||
Msg.info(this, message);
|
||||
PdbLog.message(message);
|
||||
void apply() throws PdbException, CancelledException {
|
||||
pdbLogAndInfoMessage(this,
|
||||
"Cannot apply " + this.getClass().getSimpleName() + " directly to program");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyTo(AbstractMsSymbolApplier applyToApplier) {
|
||||
void applyTo(MsSymbolApplier applyToApplier) {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void manageBlockNesting(AbstractMsSymbolApplier applierParam) {
|
||||
void manageBlockNesting(MsSymbolApplier applierParam) {
|
||||
if (applierParam instanceof FunctionSymbolApplier) {
|
||||
FunctionSymbolApplier functionSymbolApplier = (FunctionSymbolApplier) applierParam;
|
||||
Address address = applicator.reladdr(symbol);
|
||||
Address address = applicator.getAddress(symbol);
|
||||
functionSymbolApplier.beginBlock(address, symbol.getName(), symbol.getLength());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@ import ghidra.util.task.TaskMonitor;
|
|||
|
||||
/**
|
||||
* Two-way Maps forward references with corresponding definitions for composites and enums.
|
||||
* Uses the fwdref and definition members of the AbstractComplexTypeApplier.
|
||||
* Uses the forward reference and definition members of the AbstractComplexTypeApplier.
|
||||
*/
|
||||
// We have probably tried 5 or more ways of doing this, all with mixed results. The current
|
||||
// implementation seems to yield the best results at the moment. Keeping some of the old code
|
||||
|
@ -57,7 +57,7 @@ public class ComplexTypeApplierMapper {
|
|||
while (indexNumber < indexLimit) {
|
||||
monitor.checkCanceled();
|
||||
PdbResearch.checkBreak(indexNumber);
|
||||
AbstractMsTypeApplier applier =
|
||||
MsTypeApplier applier =
|
||||
applicator.getTypeApplier(RecordNumber.typeRecordNumber(indexNumber++));
|
||||
// From real data, we know that an enum and a composite both had the same SymbolPath,
|
||||
// so enums and composites must be maintained separately so they do not get matched
|
||||
|
@ -93,13 +93,14 @@ public class ComplexTypeApplierMapper {
|
|||
if (appliers == null) {
|
||||
appliers = new LinkedList<>();
|
||||
applierQueueBySymbolPath.put(symbolPath, appliers);
|
||||
// Putting fwdref or def (doesn't matter which it is)
|
||||
// Putting forward reference or definition (doesn't matter which it is)
|
||||
if (!appliers.add(complexApplier)) {
|
||||
// Error
|
||||
}
|
||||
}
|
||||
else if (appliers.peekFirst().isForwardReference() == complexApplier.isForwardReference()) {
|
||||
// Only need to look at first on list, as all on list are the same fwdref or def.
|
||||
// Only need to look at first on list, as all on list are the same forward reference
|
||||
// of definition.
|
||||
// If same as what is on list, add to the list.
|
||||
if (!appliers.add(complexApplier)) {
|
||||
// Error
|
||||
|
@ -107,14 +108,14 @@ public class ComplexTypeApplierMapper {
|
|||
}
|
||||
else {
|
||||
if (complexApplier.isForwardReference()) {
|
||||
AbstractComplexTypeApplier defApplier = appliers.removeFirst();
|
||||
defApplier.setFwdRefApplier(complexApplier);
|
||||
complexApplier.setDefinitionApplier(defApplier);
|
||||
AbstractComplexTypeApplier definitionApplier = appliers.removeFirst();
|
||||
definitionApplier.setForwardReferenceApplier(complexApplier);
|
||||
complexApplier.setDefinitionApplier(definitionApplier);
|
||||
}
|
||||
else {
|
||||
AbstractComplexTypeApplier fwdApplier = appliers.removeFirst();
|
||||
fwdApplier.setDefinitionApplier(complexApplier);
|
||||
complexApplier.setFwdRefApplier(fwdApplier);
|
||||
AbstractComplexTypeApplier forwardReferenceApplier = appliers.removeFirst();
|
||||
forwardReferenceApplier.setDefinitionApplier(complexApplier);
|
||||
complexApplier.setForwardReferenceApplier(forwardReferenceApplier);
|
||||
}
|
||||
if (appliers.isEmpty()) {
|
||||
// Do not need to keep all of these around.
|
||||
|
@ -164,7 +165,7 @@ public class ComplexTypeApplierMapper {
|
|||
// }
|
||||
// }
|
||||
//
|
||||
// // Only caching forward ref and then mapping only following def to fwdref.
|
||||
// // Only caching forward ref and then mapping only following def to forward reference.
|
||||
// // Clearing cache after that def so next def does not map.
|
||||
// private void mapComplexApplierForwardOnly(AbstractComplexTypeApplier complexApplier) {
|
||||
// SymbolPath symbolPath = complexApplier.getSymbolPath();
|
||||
|
|
|
@ -18,6 +18,9 @@ package ghidra.app.util.pdb.pdbapplicator;
|
|||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* PDB Analyzer Options Mode for performing object-oriented structure layout.
|
||||
*/
|
||||
public enum CompositeLayoutMode {
|
||||
MEMBERS_ONLY("Legacy", 0, OoComponentLayoutMode.MEMBERS_ONLY),
|
||||
BASIC_SIMPLE_COMPLEX("Complex with Basic Fallback", 1, OoComponentLayoutMode.BASIC),
|
||||
|
@ -31,7 +34,7 @@ public enum CompositeLayoutMode {
|
|||
}
|
||||
}
|
||||
|
||||
public final String label;
|
||||
private final String label;
|
||||
private final int value;
|
||||
private OoComponentLayoutMode layoutMode;
|
||||
|
||||
|
@ -46,7 +49,7 @@ public enum CompositeLayoutMode {
|
|||
this.layoutMode = layoutMode;
|
||||
}
|
||||
|
||||
public OoComponentLayoutMode getLayoutMode() {
|
||||
OoComponentLayoutMode getLayoutMode() {
|
||||
return layoutMode;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,10 +31,11 @@ import ghidra.util.exception.CancelledException;
|
|||
/*
|
||||
* Non java-doc:
|
||||
* Some truths:
|
||||
* For AbstractMsCompositeType: do not count on "count" to be zero when MsProperty is fwdref
|
||||
* (we have seen example of count==0 and not fwdref, though the majority of the time the
|
||||
* two go hand-in-hand. When these did not equate, it might have been when there was no
|
||||
* need for a fwdref and possibly only one definition--this would require a closer look).
|
||||
* For AbstractMsCompositeType: do not count on "count" to be zero when MsProperty is forward
|
||||
* reference (we have seen example of count==0 and not forward reference, though the majority
|
||||
* of the time the two go hand-in-hand. When these did not equate, it might have been when
|
||||
* there was no need for a forward reference and possibly only one definition--this would
|
||||
* require a closer look).
|
||||
*/
|
||||
/**
|
||||
* Applier for {@link AbstractCompositeMsType} types.
|
||||
|
@ -53,33 +54,21 @@ public class CompositeTypeApplier extends AbstractComplexTypeApplier {
|
|||
//
|
||||
private Map<Integer, String> componentComments;
|
||||
|
||||
private List<Default2PdbMember> members;
|
||||
|
||||
private static AbstractMsType validateType(AbstractMsType type)
|
||||
throws IllegalArgumentException {
|
||||
if (!(type instanceof AbstractCompositeMsType)) {
|
||||
throw new IllegalArgumentException(
|
||||
"PDB Incorrectly applying " + type.getClass().getSimpleName() + " to " +
|
||||
CompositeTypeApplier.class.getSimpleName());
|
||||
}
|
||||
return type;
|
||||
}
|
||||
private List<DefaultPdbUniversalMember> members;
|
||||
|
||||
/**
|
||||
* Constructor for composite type applier, for transforming a composite into a
|
||||
* Ghidra DataType.
|
||||
* Ghidra DataType.
|
||||
* @param applicator {@link PdbApplicator} for which this class is working.
|
||||
* @param msType {@link AbstractCompositeMsType} to process.
|
||||
* @throws IllegalArgumentException Upon invalid arguments.
|
||||
*/
|
||||
public CompositeTypeApplier(PdbApplicator applicator, AbstractMsType msType)
|
||||
throws IllegalArgumentException {
|
||||
super(applicator, validateType(msType));
|
||||
String fullPathName = ((AbstractCompositeMsType) msType).getName();
|
||||
public CompositeTypeApplier(PdbApplicator applicator, AbstractCompositeMsType msType) {
|
||||
super(applicator, msType);
|
||||
String fullPathName = msType.getName();
|
||||
symbolPath = new SymbolPath(SymbolPathParser.parse(fullPathName));
|
||||
}
|
||||
|
||||
public CppCompositeType getClassType() {
|
||||
CppCompositeType getClassType() {
|
||||
if (definitionApplier != null) {
|
||||
return ((CompositeTypeApplier) definitionApplier).getClassTypeInternal();
|
||||
}
|
||||
|
@ -90,33 +79,25 @@ public class CompositeTypeApplier extends AbstractComplexTypeApplier {
|
|||
return classType;
|
||||
}
|
||||
|
||||
List<Default2PdbMember> getMembers() {
|
||||
List<DefaultPdbUniversalMember> getMembers() {
|
||||
return members;
|
||||
}
|
||||
|
||||
// Mapping of fwdRef/def must be done prior to this call.
|
||||
// Mapping of forwardReference/definition must be done prior to this call.
|
||||
private void getOrCreateComposite() {
|
||||
if (dataType != null) {
|
||||
return;
|
||||
}
|
||||
if (isForwardReference()) {
|
||||
if (definitionApplier != null) {
|
||||
dataType = definitionApplier.getDataTypeInternal();
|
||||
classType = ((CompositeTypeApplier) definitionApplier).getClassTypeInternal();
|
||||
if (dataType != null) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
AbstractComplexTypeApplier alternativeApplier = getAlternativeTypeApplier();
|
||||
if (alternativeApplier != null) {
|
||||
dataType = alternativeApplier.getDataTypeInternal();
|
||||
classType = ((CompositeTypeApplier) alternativeApplier).getClassTypeInternal();
|
||||
}
|
||||
else {
|
||||
if (fwdRefApplier != null) {
|
||||
dataType = fwdRefApplier.getDataTypeInternal();
|
||||
classType = ((CompositeTypeApplier) fwdRefApplier).getClassTypeInternal();
|
||||
if (dataType != null) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (dataType != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
dataType = createEmptyComposite((AbstractCompositeMsType) msType);
|
||||
String mangledName = ((AbstractCompositeMsType) msType).getMangledName();
|
||||
classType = new CppCompositeType((Composite) dataType, mangledName);
|
||||
|
@ -136,7 +117,7 @@ public class CompositeTypeApplier extends AbstractComplexTypeApplier {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void apply() throws PdbException, CancelledException {
|
||||
void apply() throws PdbException, CancelledException {
|
||||
|
||||
getOrCreateComposite();
|
||||
|
||||
|
@ -154,7 +135,7 @@ public class CompositeTypeApplier extends AbstractComplexTypeApplier {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void resolve() {
|
||||
void resolve() {
|
||||
if (!isForwardReference()) {
|
||||
super.resolve();
|
||||
}
|
||||
|
@ -176,10 +157,10 @@ public class CompositeTypeApplier extends AbstractComplexTypeApplier {
|
|||
|
||||
// Currently do not need this dependency, as we currently do not need any contents
|
||||
// of the base class for filling in this class
|
||||
for (AbstractMsTypeApplier baseApplierIterated : fieldListApplier.getBaseClassList()) {
|
||||
for (MsTypeApplier baseApplierIterated : fieldListApplier.getBaseClassList()) {
|
||||
if (baseApplierIterated instanceof BaseClassTypeApplier) {
|
||||
BaseClassTypeApplier baseTypeApplier = (BaseClassTypeApplier) baseApplierIterated;
|
||||
AbstractMsTypeApplier applier =
|
||||
MsTypeApplier applier =
|
||||
applicator.getTypeApplier(baseTypeApplier.getBaseClassRecordNumber());
|
||||
if (applier instanceof CompositeTypeApplier) {
|
||||
CompositeTypeApplier dependencyApplier =
|
||||
|
@ -197,11 +178,11 @@ public class CompositeTypeApplier extends AbstractComplexTypeApplier {
|
|||
}
|
||||
}
|
||||
}
|
||||
for (AbstractMsTypeApplier memberTypeApplierIterated : fieldListApplier.getMemberList()) {
|
||||
for (MsTypeApplier memberTypeApplierIterated : fieldListApplier.getMemberList()) {
|
||||
applicator.checkCanceled();
|
||||
if (memberTypeApplierIterated instanceof MemberTypeApplier) {
|
||||
MemberTypeApplier memberTypeApplier = (MemberTypeApplier) memberTypeApplierIterated;
|
||||
AbstractMsTypeApplier fieldApplier = memberTypeApplier.getFieldTypeApplier();
|
||||
MsTypeApplier fieldApplier = memberTypeApplier.getFieldTypeApplier();
|
||||
recurseAddDependency(fieldApplier);
|
||||
}
|
||||
// if (memberTypeApplierIterated instanceof NestedTypeApplier) {
|
||||
|
@ -216,8 +197,10 @@ public class CompositeTypeApplier extends AbstractComplexTypeApplier {
|
|||
}
|
||||
}
|
||||
|
||||
private void recurseAddDependency(AbstractMsTypeApplier dependee)
|
||||
private void recurseAddDependency(MsTypeApplier dependee)
|
||||
throws CancelledException, PdbException {
|
||||
// TODO: evaluate this and make changes... this work might be being taken care of in
|
||||
// ModifierTypeApplier
|
||||
if (dependee instanceof ModifierTypeApplier) {
|
||||
ModifierTypeApplier modifierApplier = (ModifierTypeApplier) dependee;
|
||||
recurseAddDependency(modifierApplier.getModifiedTypeApplier());
|
||||
|
@ -233,6 +216,8 @@ public class CompositeTypeApplier extends AbstractComplexTypeApplier {
|
|||
}
|
||||
setDeferred();
|
||||
}
|
||||
// TODO: evaluate this and make changes... this work might be being taken care of in
|
||||
// ArrayTypeApplier
|
||||
else if (dependee instanceof ArrayTypeApplier) {
|
||||
applicator.addApplierDependency(this, dependee);
|
||||
setDeferred();
|
||||
|
@ -251,7 +236,7 @@ public class CompositeTypeApplier extends AbstractComplexTypeApplier {
|
|||
else if (dependee instanceof BitfieldTypeApplier) {
|
||||
RecordNumber recNum =
|
||||
((AbstractBitfieldMsType) ((BitfieldTypeApplier) dependee).getMsType()).getElementRecordNumber();
|
||||
AbstractMsTypeApplier underlyingApplier = applicator.getTypeApplier(recNum);
|
||||
MsTypeApplier underlyingApplier = applicator.getTypeApplier(recNum);
|
||||
if (underlyingApplier instanceof EnumTypeApplier) {
|
||||
applicator.addApplierDependency(this, underlyingApplier);
|
||||
setDeferred();
|
||||
|
@ -260,7 +245,7 @@ public class CompositeTypeApplier extends AbstractComplexTypeApplier {
|
|||
//We are assuming that bitfields on typedefs will not be defined.
|
||||
}
|
||||
|
||||
public void applyInternal() throws CancelledException, PdbException {
|
||||
private void applyInternal() throws CancelledException, PdbException {
|
||||
|
||||
if (isApplied()) {
|
||||
return;
|
||||
|
@ -273,9 +258,8 @@ public class CompositeTypeApplier extends AbstractComplexTypeApplier {
|
|||
if (type instanceof AbstractUnionMsType) {
|
||||
applyCpp = false;
|
||||
if (hasBaseClasses()) {
|
||||
String msg = "Unexpected base classes for union type: " + type.getName();
|
||||
PdbLog.message(msg);
|
||||
Msg.info(this, msg);
|
||||
pdbLogAndInfoMessage(this,
|
||||
"Unexpected base classes for union type: " + type.getName());
|
||||
}
|
||||
}
|
||||
if (applyCpp) {
|
||||
|
@ -288,7 +272,7 @@ public class CompositeTypeApplier extends AbstractComplexTypeApplier {
|
|||
}
|
||||
|
||||
//==============================================================================================
|
||||
void applyBasic(Composite composite, AbstractCompositeMsType type)
|
||||
private void applyBasic(Composite composite, AbstractCompositeMsType type)
|
||||
throws CancelledException, PdbException {
|
||||
|
||||
//boolean isClass = (type instanceof AbstractClassMsType || actsLikeClass(applicator, type));
|
||||
|
@ -320,10 +304,8 @@ public class CompositeTypeApplier extends AbstractComplexTypeApplier {
|
|||
for (Map.Entry<Integer, String> entry : componentComments.entrySet()) {
|
||||
DataTypeComponent component = structure.getComponentAt(entry.getKey());
|
||||
if (component == null) {
|
||||
String message = "Could not set comment for 'missing' componenent " +
|
||||
entry.getKey() + " for: " + structure.getName();
|
||||
PdbLog.message(message);
|
||||
Msg.info(this, message);
|
||||
pdbLogAndInfoMessage(this, "Could not set comment for 'missing' componenent " +
|
||||
entry.getKey() + " for: " + structure.getName());
|
||||
return;
|
||||
}
|
||||
component.setComment(entry.getValue());
|
||||
|
@ -332,7 +314,7 @@ public class CompositeTypeApplier extends AbstractComplexTypeApplier {
|
|||
}
|
||||
|
||||
//==============================================================================================
|
||||
void applyCpp(Composite composite, AbstractCompositeMsType type)
|
||||
private void applyCpp(Composite composite, AbstractCompositeMsType type)
|
||||
throws PdbException, CancelledException {
|
||||
// Fill in composite definition details.
|
||||
FieldListTypeApplier fieldListApplier = FieldListTypeApplier.getFieldListApplierSpecial(
|
||||
|
@ -362,15 +344,6 @@ public class CompositeTypeApplier extends AbstractComplexTypeApplier {
|
|||
}
|
||||
|
||||
//==============================================================================================
|
||||
public void setDeferred() {
|
||||
isDeferred = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDeferred() {
|
||||
return isDeferred;
|
||||
}
|
||||
|
||||
@Override
|
||||
void deferredApply() throws PdbException, CancelledException {
|
||||
if (isDeferred()) {
|
||||
|
@ -381,19 +354,19 @@ public class CompositeTypeApplier extends AbstractComplexTypeApplier {
|
|||
//==============================================================================================
|
||||
//==============================================================================================
|
||||
@Override
|
||||
public CompositeTypeApplier getDependencyApplier() {
|
||||
CompositeTypeApplier getDependencyApplier() {
|
||||
if (definitionApplier != null && definitionApplier instanceof CompositeTypeApplier) {
|
||||
return (CompositeTypeApplier) definitionApplier;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
String getName() {
|
||||
return getMsType().getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataType getDataType() {
|
||||
DataType getDataType() {
|
||||
if (resolved) {
|
||||
return resolvedDataType;
|
||||
}
|
||||
|
@ -409,12 +382,12 @@ public class CompositeTypeApplier extends AbstractComplexTypeApplier {
|
|||
return dataType;
|
||||
}
|
||||
|
||||
public boolean hasUniqueName() {
|
||||
boolean hasUniqueName() {
|
||||
return ((AbstractCompositeMsType) msType).getMsProperty().hasUniqueName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BigInteger getSize() {
|
||||
BigInteger getSize() {
|
||||
return ((AbstractCompositeMsType) getDependencyApplier().getMsType()).getSize();
|
||||
}
|
||||
|
||||
|
@ -472,7 +445,7 @@ public class CompositeTypeApplier extends AbstractComplexTypeApplier {
|
|||
else {
|
||||
defType = (AbstractCompositeMsType) definitionApplier.getMsType();
|
||||
}
|
||||
AbstractMsTypeApplier applier =
|
||||
MsTypeApplier applier =
|
||||
applicator.getTypeApplier(defType.getFieldDescriptorListRecordNumber());
|
||||
if (!(applier instanceof FieldListTypeApplier)) {
|
||||
return false;
|
||||
|
@ -504,7 +477,7 @@ public class CompositeTypeApplier extends AbstractComplexTypeApplier {
|
|||
// So... it might not be good to return "true" for just checking if the type is an
|
||||
// instanceof AbstractClassMsType.
|
||||
|
||||
AbstractMsTypeApplier applier =
|
||||
MsTypeApplier applier =
|
||||
applicator.getTypeApplier(defType.getFieldDescriptorListRecordNumber());
|
||||
if (!(applier instanceof FieldListTypeApplier)) {
|
||||
return false;
|
||||
|
@ -522,14 +495,14 @@ public class CompositeTypeApplier extends AbstractComplexTypeApplier {
|
|||
|
||||
AbstractCompositeMsType type = (AbstractCompositeMsType) msType;
|
||||
|
||||
for (AbstractMsTypeApplier baseApplierIterated : fieldListApplier.getBaseClassList()) {
|
||||
for (MsTypeApplier baseApplierIterated : fieldListApplier.getBaseClassList()) {
|
||||
if (!(baseApplierIterated instanceof BaseClassTypeApplier)) {
|
||||
applicator.appendLogMsg(baseApplierIterated.getClass().getSimpleName() +
|
||||
" seen where BaseClassTypeApplier expected for " + type.getName());
|
||||
continue;
|
||||
}
|
||||
BaseClassTypeApplier baseTypeApplier = (BaseClassTypeApplier) baseApplierIterated;
|
||||
AbstractMsTypeApplier baseClassTypeApplier =
|
||||
MsTypeApplier baseClassTypeApplier =
|
||||
applicator.getTypeApplier(baseTypeApplier.getBaseClassRecordNumber());
|
||||
if (!(baseClassTypeApplier instanceof CompositeTypeApplier)) {
|
||||
applicator.appendLogMsg(baseApplierIterated.getClass().getSimpleName() +
|
||||
|
@ -599,7 +572,7 @@ public class CompositeTypeApplier extends AbstractComplexTypeApplier {
|
|||
}
|
||||
|
||||
private CppCompositeType getUnderlyingClassType(RecordNumber recordNumber) {
|
||||
AbstractMsTypeApplier baseUnderlyingApplier = applicator.getTypeApplier(recordNumber);
|
||||
MsTypeApplier baseUnderlyingApplier = applicator.getTypeApplier(recordNumber);
|
||||
if (!(baseUnderlyingApplier instanceof CompositeTypeApplier)) {
|
||||
applicator.appendLogMsg(baseUnderlyingApplier.getClass().getSimpleName() +
|
||||
" seen where CompositeTypeApplier expected for base class.");
|
||||
|
@ -614,7 +587,7 @@ public class CompositeTypeApplier extends AbstractComplexTypeApplier {
|
|||
}
|
||||
|
||||
private DataType getVirtualBaseTablePointerDataType(RecordNumber recordNumber) {
|
||||
AbstractMsTypeApplier vbptrApplier = applicator.getTypeApplier(recordNumber);
|
||||
MsTypeApplier vbptrApplier = applicator.getTypeApplier(recordNumber);
|
||||
if (vbptrApplier != null) {
|
||||
if (vbptrApplier instanceof PointerTypeApplier) {
|
||||
return vbptrApplier.getDataType();
|
||||
|
@ -663,7 +636,7 @@ public class CompositeTypeApplier extends AbstractComplexTypeApplier {
|
|||
|
||||
AbstractCompositeMsType type = (AbstractCompositeMsType) msType;
|
||||
|
||||
for (AbstractMsTypeApplier memberTypeApplierIterated : fieldListApplier.getMemberList()) {
|
||||
for (MsTypeApplier memberTypeApplierIterated : fieldListApplier.getMemberList()) {
|
||||
boolean handled = true;
|
||||
if (memberTypeApplierIterated instanceof MemberTypeApplier) {
|
||||
MemberTypeApplier memberTypeApplier = (MemberTypeApplier) memberTypeApplierIterated;
|
||||
|
@ -673,7 +646,7 @@ public class CompositeTypeApplier extends AbstractComplexTypeApplier {
|
|||
PdbApplicator.bigIntegerToInt(applicator, memberTypeApplier.getOffset());
|
||||
ClassFieldMsAttributes memberAttributes = memberTypeApplier.getAttribute();
|
||||
memberAttributes.getAccess(); // TODO: do something with this and other attributes
|
||||
AbstractMsTypeApplier fieldApplier = memberTypeApplier.getFieldTypeApplier();
|
||||
MsTypeApplier fieldApplier = memberTypeApplier.getFieldTypeApplier();
|
||||
|
||||
if (fieldApplier instanceof CompositeTypeApplier) {
|
||||
CompositeTypeApplier defApplier =
|
||||
|
@ -694,8 +667,8 @@ public class CompositeTypeApplier extends AbstractComplexTypeApplier {
|
|||
if (fieldDataType == null) {
|
||||
if (fieldApplier instanceof PrimitiveTypeApplier &&
|
||||
((PrimitiveTypeApplier) fieldApplier).isNoType()) {
|
||||
Default2PdbMember member =
|
||||
new Default2PdbMember(applicator, memberName, fieldApplier, offset);
|
||||
DefaultPdbUniversalMember member = new DefaultPdbUniversalMember(applicator,
|
||||
memberName, fieldApplier, offset);
|
||||
members.add(member);
|
||||
componentComments.put(offset, "NO_TYPE");
|
||||
}
|
||||
|
@ -706,8 +679,8 @@ public class CompositeTypeApplier extends AbstractComplexTypeApplier {
|
|||
}
|
||||
}
|
||||
else {
|
||||
Default2PdbMember member =
|
||||
new Default2PdbMember(applicator, memberName, fieldApplier, offset);
|
||||
DefaultPdbUniversalMember member =
|
||||
new DefaultPdbUniversalMember(applicator, memberName, fieldApplier, offset);
|
||||
members.add(member);
|
||||
classType.addMember(memberName, fieldDataType, isFlexibleArray,
|
||||
convertAttributes(memberAttributes), offset);
|
||||
|
@ -719,16 +692,17 @@ public class CompositeTypeApplier extends AbstractComplexTypeApplier {
|
|||
String fieldName = enumerateTypeApplier.getName();
|
||||
Numeric numeric = enumerateTypeApplier.getNumeric();
|
||||
// TODO: some work
|
||||
PdbLog.message("Don't know how to apply EnumerateTypeApplier fieldName " +
|
||||
fieldName + " and value " + numeric + " within " + msType.getName());
|
||||
pdbLogAndInfoMessage(this,
|
||||
"Don't know how to apply EnumerateTypeApplier fieldName " + fieldName +
|
||||
" and value " + numeric + " within " + msType.getName());
|
||||
}
|
||||
else if (memberTypeApplierIterated instanceof VirtualFunctionTablePointerTypeApplier) {
|
||||
VirtualFunctionTablePointerTypeApplier vtPtrApplier =
|
||||
(VirtualFunctionTablePointerTypeApplier) memberTypeApplierIterated;
|
||||
String vftPtrMemberName = vtPtrApplier.getMemberName();
|
||||
int offset = vtPtrApplier.getOffset();
|
||||
Default2PdbMember member =
|
||||
new Default2PdbMember(applicator, vftPtrMemberName, vtPtrApplier, offset);
|
||||
DefaultPdbUniversalMember member = new DefaultPdbUniversalMember(applicator,
|
||||
vftPtrMemberName, vtPtrApplier, offset);
|
||||
members.add(member);
|
||||
//classType.addMember(vftPtrMemberName, vtPtrApplier.getDataType(), false, offset);
|
||||
classType.addVirtualFunctionTablePointer(vftPtrMemberName,
|
||||
|
@ -754,8 +728,8 @@ public class CompositeTypeApplier extends AbstractComplexTypeApplier {
|
|||
// We are skipping because we've had issues and do not know what is going on
|
||||
// at the moment. (I think they were dependency issues... been a while.)
|
||||
// See not above the "if" condition.
|
||||
// PdbLog.message("Skipping Composite Nested type member: " + memberName +
|
||||
// " within " + type.getName());
|
||||
// pdbLogAndInfoMessage(this, "Skipping Composite Nested type member: " +
|
||||
// memberName + " within " + type.getName());
|
||||
// TODO: Investigate. What does it mean when the internally defined type
|
||||
// conficts with the name of the outer type.
|
||||
continue;
|
||||
|
|
|
@ -31,7 +31,8 @@ import ghidra.util.exception.CancelledException;
|
|||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
/**
|
||||
* Notional C++ Class Type.
|
||||
* Notional C++ Class Type. Much work has yet to be done with this class. For instance, the plan
|
||||
* is to continue to break this class up into smaller self-contained classes.
|
||||
*/
|
||||
public class CppCompositeType {
|
||||
|
||||
|
@ -305,7 +306,7 @@ public class CppCompositeType {
|
|||
|
||||
//==============================================================================================
|
||||
/*
|
||||
* These "insert" methods should be used judiciously. You need to know what/why you are doing
|
||||
* These "insert" methods should be used judiciously. You need to know what/why you are doing
|
||||
* this. Changing the order of "normal" members can mess up the layout algorithms from
|
||||
* {@link DefaultCompositeMember}. The only place we currently think we can use these is
|
||||
* when trying to place vbptr members. Not all of these methods are used too.
|
||||
|
|
|
@ -24,16 +24,23 @@ import ghidra.program.model.address.Address;
|
|||
import ghidra.program.model.data.*;
|
||||
import ghidra.program.model.listing.*;
|
||||
import ghidra.program.model.mem.DumbMemBufferImpl;
|
||||
import ghidra.program.model.util.CodeUnitInsertionException;
|
||||
import ghidra.util.exception.AssertException;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
|
||||
/**
|
||||
* Applier for {@link AbstractDataMsSymbol} symbols.
|
||||
*/
|
||||
public class DataSymbolApplier extends AbstractMsSymbolApplier {
|
||||
public class DataSymbolApplier extends MsSymbolApplier {
|
||||
|
||||
private AbstractDataMsSymbol symbol;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param applicator the {@link PdbApplicator} for which we are working.
|
||||
* @param iter the Iterator containing the symbol sequence being processed
|
||||
* @throws CancelledException upon user cancellation
|
||||
*/
|
||||
public DataSymbolApplier(PdbApplicator applicator, AbstractMsSymbolIterator iter) {
|
||||
super(applicator, iter);
|
||||
AbstractMsSymbol abstractSymbol = iter.next();
|
||||
|
@ -45,47 +52,46 @@ public class DataSymbolApplier extends AbstractMsSymbolApplier {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void applyTo(AbstractMsSymbolApplier applyToApplier)
|
||||
throws PdbException, CancelledException {
|
||||
void applyTo(MsSymbolApplier applyToApplier) throws PdbException, CancelledException {
|
||||
if (applyToApplier instanceof FunctionSymbolApplier) {
|
||||
FunctionSymbolApplier functionSymbolApplier = (FunctionSymbolApplier) applyToApplier;
|
||||
if (symbol.getSegment() == 0 && symbol.getOffset() == 0L) {
|
||||
return; // silently return.
|
||||
}
|
||||
AbstractMsTypeApplier applier = getTypeApplier();
|
||||
MsTypeApplier applier = getTypeApplier();
|
||||
DataType dataType = applier.getDataType();
|
||||
if (dataType == null) { // TODO: check that we can have null here.
|
||||
return; // silently return.
|
||||
}
|
||||
String name = symbol.getName();
|
||||
Address address = applicator.reladdr(symbol);
|
||||
Address address = applicator.getAddress(symbol);
|
||||
|
||||
functionSymbolApplier.setLocalVariable(address, name, dataType);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply() throws CancelledException, PdbException {
|
||||
void apply() throws CancelledException, PdbException {
|
||||
// skip if both zero (i.e,. process if either is not zero)
|
||||
if (symbol.getSegment() != 0 || symbol.getOffset() != 0L) {
|
||||
Address symbolAddress = applicator.reladdr(symbol);
|
||||
Address symbolAddress = applicator.getAddress(symbol);
|
||||
Address remapAddress = applicator.getRemapAddressByAddress(symbolAddress);
|
||||
RecordNumber typeRecordNumber = symbol.getTypeRecordNumber();
|
||||
boolean forcePrimary = applicator.shouldForcePrimarySymbol(symbolAddress, true);
|
||||
boolean forcePrimary = applicator.shouldForcePrimarySymbol(remapAddress, true);
|
||||
String name = symbol.getName();
|
||||
if (!applicator.createSymbol(symbolAddress, name, forcePrimary)) {
|
||||
applicator.appendLogMsg("Unable to create symbol " + name + " at " + symbolAddress);
|
||||
if (!applicator.createSymbol(remapAddress, name, forcePrimary)) {
|
||||
applicator.appendLogMsg("Unable to create symbol " + name + " at " + remapAddress);
|
||||
}
|
||||
createData(symbolAddress, typeRecordNumber);
|
||||
createData(remapAddress, typeRecordNumber);
|
||||
}
|
||||
}
|
||||
|
||||
AbstractMsTypeApplier getTypeApplier() {
|
||||
MsTypeApplier getTypeApplier() {
|
||||
return applicator.getTypeApplier(symbol.getTypeRecordNumber());
|
||||
}
|
||||
|
||||
void createData(Address address, RecordNumber typeRecordNumber) {
|
||||
AbstractMsTypeApplier applier = applicator.getTypeApplier(typeRecordNumber);
|
||||
MsTypeApplier applier = applicator.getTypeApplier(typeRecordNumber);
|
||||
if (applier == null) {
|
||||
applicator.appendLogMsg("Error: Failed to resolve datatype RecordNumber " +
|
||||
typeRecordNumber + " at " + address);
|
||||
|
@ -168,7 +174,7 @@ public class DataSymbolApplier extends AbstractMsSymbolApplier {
|
|||
applicator.getProgram().getListing().createData(address, dataType);
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
catch (CodeUnitInsertionException | DataTypeConflictException e) {
|
||||
applicator.appendLogMsg("Unable to create " + dataType.getDisplayName() + " at 0x" +
|
||||
address + ": " + e.getMessage());
|
||||
}
|
||||
|
@ -179,7 +185,7 @@ public class DataSymbolApplier extends AbstractMsSymbolApplier {
|
|||
address.add(dataTypeLength - 1), false);
|
||||
applicator.getProgram().getListing().createData(address, dataType, dataTypeLength);
|
||||
}
|
||||
catch (Exception e) {
|
||||
catch (CodeUnitInsertionException | DataTypeConflictException e) {
|
||||
applicator.appendLogMsg("Unable to replace " + dataType.getDisplayName() +
|
||||
" at 0x" + address + ": " + e.getMessage());
|
||||
}
|
||||
|
|
|
@ -25,9 +25,9 @@ import ghidra.util.exception.CancelledException;
|
|||
* <code>PdbMember</code> convey PDB member information used for datatype
|
||||
* reconstruction.
|
||||
*/
|
||||
public class Default2PdbMember extends PdbMember {
|
||||
public class DefaultPdbUniversalMember extends PdbMember {
|
||||
|
||||
private AbstractMsTypeApplier applier;
|
||||
private MsTypeApplier applier;
|
||||
private DataType dataType;
|
||||
|
||||
/**
|
||||
|
@ -36,10 +36,10 @@ public class Default2PdbMember extends PdbMember {
|
|||
* @param name member field name. For bitfields this also conveys the bit-size
|
||||
* and optionally the bit-offset.
|
||||
* @param applier fieldApplier for the field datatype or base datatype associated with the
|
||||
* bitfield.
|
||||
* bitfield.
|
||||
* @param offset member's byte offset within the root composite.
|
||||
*/
|
||||
Default2PdbMember(PdbApplicator applicator, String name, AbstractMsTypeApplier applier,
|
||||
DefaultPdbUniversalMember(PdbApplicator applicator, String name, MsTypeApplier applier,
|
||||
int offset) {
|
||||
super(name, (applier.getDataType()).getName(), offset, null);
|
||||
this.applier = applier;
|
||||
|
@ -54,13 +54,14 @@ public class Default2PdbMember extends PdbMember {
|
|||
* @param dataType for the field.
|
||||
* @param offset member's byte offset within the root composite.
|
||||
*/
|
||||
Default2PdbMember(PdbApplicator applicator, String name, DataType dataType, int offset) {
|
||||
DefaultPdbUniversalMember(PdbApplicator applicator, String name, DataType dataType,
|
||||
int offset) {
|
||||
super(name, dataType.getName(), offset, null);
|
||||
this.applier = null;
|
||||
this.dataType = dataType;
|
||||
}
|
||||
|
||||
AbstractMsTypeApplier getApplier() {
|
||||
MsTypeApplier getApplier() {
|
||||
return applier;
|
||||
}
|
||||
|
|
@ -16,20 +16,23 @@
|
|||
package ghidra.app.util.pdb.pdbapplicator;
|
||||
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.PdbException;
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.PdbLog;
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.symbol.*;
|
||||
import ghidra.app.util.pdb.pdbapplicator.SymbolGroup.AbstractMsSymbolIterator;
|
||||
import ghidra.util.Msg;
|
||||
import ghidra.util.exception.AssertException;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
|
||||
/**
|
||||
* Applier for {@link AbstractDefinedSingleAddressRangeMsSymbol} symbols.
|
||||
*/
|
||||
public class DefinedSingleAddressRangeSymbolApplier extends AbstractMsSymbolApplier {
|
||||
public class DefinedSingleAddressRangeSymbolApplier extends MsSymbolApplier {
|
||||
|
||||
private AbstractDefinedSingleAddressRangeMsSymbol symbol;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param applicator the {@link PdbApplicator} for which we are working.
|
||||
* @param iter the Iterator containing the symbol sequence being processed
|
||||
*/
|
||||
public DefinedSingleAddressRangeSymbolApplier(PdbApplicator applicator,
|
||||
AbstractMsSymbolIterator iter) {
|
||||
super(applicator, iter);
|
||||
|
@ -42,15 +45,13 @@ public class DefinedSingleAddressRangeSymbolApplier extends AbstractMsSymbolAppl
|
|||
}
|
||||
|
||||
@Override
|
||||
public void apply() throws PdbException, CancelledException {
|
||||
String message = "Cannot apply " + this.getClass().getSimpleName() + " directly to program";
|
||||
Msg.info(this, message);
|
||||
PdbLog.message(message);
|
||||
void apply() throws PdbException, CancelledException {
|
||||
pdbLogAndInfoMessage(this,
|
||||
"Cannot apply " + this.getClass().getSimpleName() + " directly to program");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyTo(AbstractMsSymbolApplier applyToApplier)
|
||||
throws PdbException, CancelledException {
|
||||
void applyTo(MsSymbolApplier applyToApplier) throws PdbException, CancelledException {
|
||||
if (applyToApplier instanceof LocalOptimizedSymbolApplier) {
|
||||
// TODO: eventually apply.
|
||||
// LocalOptimizedSymbolApplier localSymbolApplier =
|
||||
|
|
|
@ -16,18 +16,23 @@
|
|||
package ghidra.app.util.pdb.pdbapplicator;
|
||||
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.PdbException;
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.PdbLog;
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.symbol.AbstractMsSymbol;
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.symbol.EndMsSymbol;
|
||||
import ghidra.app.util.pdb.pdbapplicator.SymbolGroup.AbstractMsSymbolIterator;
|
||||
import ghidra.util.Msg;
|
||||
import ghidra.util.exception.AssertException;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
|
||||
/**
|
||||
* Applier for {@link EndMsSymbol} symbols.
|
||||
*/
|
||||
public class EndSymbolApplier extends AbstractMsSymbolApplier {
|
||||
public class EndSymbolApplier extends MsSymbolApplier {
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param applicator the {@link PdbApplicator} for which we are working.
|
||||
* @param iter the Iterator containing the symbol sequence being processed
|
||||
* @throws CancelledException upon user cancellation
|
||||
*/
|
||||
public EndSymbolApplier(PdbApplicator applicator, AbstractMsSymbolIterator iter) {
|
||||
super(applicator, iter);
|
||||
AbstractMsSymbol abstractSymbol = iter.next();
|
||||
|
@ -38,25 +43,23 @@ public class EndSymbolApplier extends AbstractMsSymbolApplier {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void apply() throws PdbException {
|
||||
String message =
|
||||
void apply() throws PdbException {
|
||||
pdbLogAndInfoMessage(this,
|
||||
String.format("Cannot apply %s directly to program (module:0X%04X, offset:0X%08X)",
|
||||
this.getClass().getSimpleName(), iter.getModuleNumber(), iter.getCurrentOffset());
|
||||
Msg.info(this, message);
|
||||
PdbLog.message(message);
|
||||
this.getClass().getSimpleName(), iter.getModuleNumber(), iter.getCurrentOffset()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyTo(AbstractMsSymbolApplier applyToApplier) {
|
||||
void applyTo(MsSymbolApplier applyToApplier) {
|
||||
if (!(applyToApplier instanceof FunctionSymbolApplier)) {
|
||||
return;
|
||||
}
|
||||
FunctionSymbolApplier functionSymbolApplier = (FunctionSymbolApplier) applyToApplier;
|
||||
// FunctionSymbolApplier functionSymbolApplier = (FunctionSymbolApplier) applyToApplier;
|
||||
// functionSymbolApplier.endBlock();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void manageBlockNesting(AbstractMsSymbolApplier applierParam) {
|
||||
void manageBlockNesting(MsSymbolApplier applierParam) {
|
||||
if (applierParam instanceof FunctionSymbolApplier) {
|
||||
FunctionSymbolApplier functionSymbolApplier = (FunctionSymbolApplier) applierParam;
|
||||
functionSymbolApplier.endBlock();
|
||||
|
|
|
@ -20,7 +20,8 @@ import java.util.List;
|
|||
|
||||
import ghidra.app.util.SymbolPath;
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.*;
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.type.*;
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.type.AbstractEnumMsType;
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.type.MsProperty;
|
||||
import ghidra.program.model.data.*;
|
||||
import ghidra.util.Msg;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
|
@ -35,30 +36,20 @@ public class EnumTypeApplier extends AbstractComplexTypeApplier {
|
|||
// private int length = 0;
|
||||
// private boolean isSigned = false;
|
||||
//
|
||||
private static AbstractMsType validateType(AbstractMsType type)
|
||||
throws IllegalArgumentException {
|
||||
if (!(type instanceof AbstractEnumMsType)) {
|
||||
throw new IllegalArgumentException("PDB Incorrectly applying " +
|
||||
type.getClass().getSimpleName() + " to " + EnumTypeApplier.class.getSimpleName());
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for enum type applier, for transforming a enum into a
|
||||
* Ghidra DataType.
|
||||
* Ghidra DataType.
|
||||
* @param applicator {@link PdbApplicator} for which this class is working.
|
||||
* @param msType {@link AbstractEnumMsType} to process.
|
||||
* @throws IllegalArgumentException Upon invalid arguments.
|
||||
*/
|
||||
public EnumTypeApplier(PdbApplicator applicator, AbstractMsType msType)
|
||||
throws IllegalArgumentException {
|
||||
super(applicator, validateType(msType));
|
||||
public EnumTypeApplier(PdbApplicator applicator, AbstractEnumMsType msType) {
|
||||
super(applicator, msType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BigInteger getSize() {
|
||||
AbstractMsTypeApplier underlyingApplier = getUnderlyingTypeApplier();
|
||||
BigInteger getSize() {
|
||||
MsTypeApplier underlyingApplier = getUnderlyingTypeApplier();
|
||||
if (underlyingApplier == null) {
|
||||
return BigInteger.ZERO;
|
||||
}
|
||||
|
@ -80,7 +71,7 @@ public class EnumTypeApplier extends AbstractComplexTypeApplier {
|
|||
|
||||
private int getLength() {
|
||||
// Minimum length allowed by Ghidra is 1 for enum, so all returns are min 1.
|
||||
AbstractMsTypeApplier underlyingApplier = getUnderlyingTypeApplier();
|
||||
MsTypeApplier underlyingApplier = getUnderlyingTypeApplier();
|
||||
if (underlyingApplier == null) {
|
||||
return 1;
|
||||
}
|
||||
|
@ -91,8 +82,8 @@ public class EnumTypeApplier extends AbstractComplexTypeApplier {
|
|||
return Integer.max(underlyingType.getLength(), 1);
|
||||
}
|
||||
|
||||
public boolean isSigned() {
|
||||
AbstractMsTypeApplier underlyingApplier = getUnderlyingTypeApplier();
|
||||
boolean isSigned() {
|
||||
MsTypeApplier underlyingApplier = getUnderlyingTypeApplier();
|
||||
if (underlyingApplier == null) {
|
||||
return false;
|
||||
}
|
||||
|
@ -107,20 +98,20 @@ public class EnumTypeApplier extends AbstractComplexTypeApplier {
|
|||
}
|
||||
|
||||
@Override
|
||||
public EnumTypeApplier getDependencyApplier() {
|
||||
EnumTypeApplier getDependencyApplier() {
|
||||
if (definitionApplier != null && definitionApplier instanceof EnumTypeApplier) {
|
||||
return (EnumTypeApplier) definitionApplier;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
String getName() {
|
||||
return getMsType().getName();
|
||||
}
|
||||
|
||||
private AbstractMsTypeApplier getUnderlyingTypeApplier() {
|
||||
AbstractMsTypeApplier under = null;
|
||||
AbstractMsTypeApplier applier = (definitionApplier != null) ? definitionApplier : this;
|
||||
private MsTypeApplier getUnderlyingTypeApplier() {
|
||||
MsTypeApplier under = null;
|
||||
MsTypeApplier applier = (definitionApplier != null) ? definitionApplier : this;
|
||||
RecordNumber underlyingRecordNumber =
|
||||
((AbstractEnumMsType) applier.getMsType()).getUnderlyingRecordNumber();
|
||||
under = applicator.getTypeApplier(underlyingRecordNumber);
|
||||
|
@ -131,7 +122,7 @@ public class EnumTypeApplier extends AbstractComplexTypeApplier {
|
|||
return under;
|
||||
}
|
||||
|
||||
private EnumDataType createEmptyEnum(AbstractEnumMsType type) throws PdbException {
|
||||
private EnumDataType createEmptyEnum(AbstractEnumMsType type) {
|
||||
|
||||
SymbolPath fixedPath = getFixedSymbolPath();
|
||||
CategoryPath categoryPath = applicator.getCategory(fixedPath.getParent());
|
||||
|
@ -155,10 +146,8 @@ public class EnumTypeApplier extends AbstractComplexTypeApplier {
|
|||
// isSigned = ((AbstractIntegerDataType) underlyingType).isSigned();
|
||||
// }
|
||||
// else if (!(underlyingType instanceof VoidDataType)) {
|
||||
// String msg = "Cannot processes enum with underlying type: " +
|
||||
// underlyingType.getClass().getSimpleName();
|
||||
// Msg.info(this, msg);
|
||||
// PdbLog.message(msg);
|
||||
// pdbLogAndInfoMessage(this, "Cannot processes enum with underlying type: " +
|
||||
// underlyingType.getClass().getSimpleName());
|
||||
// throw new PdbException(msg);
|
||||
// }
|
||||
// }
|
||||
|
@ -182,7 +171,7 @@ public class EnumTypeApplier extends AbstractComplexTypeApplier {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void apply() throws PdbException, CancelledException {
|
||||
void apply() throws PdbException, CancelledException {
|
||||
getOrCreateEnum();
|
||||
|
||||
AbstractEnumMsType type = (AbstractEnumMsType) msType;
|
||||
|
@ -196,14 +185,14 @@ public class EnumTypeApplier extends AbstractComplexTypeApplier {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void resolve() {
|
||||
void resolve() {
|
||||
if (!isForwardReference()) {
|
||||
super.resolve();
|
||||
}
|
||||
}
|
||||
|
||||
// Mapping of fwdRef/def must be done prior to this call.
|
||||
private void getOrCreateEnum() throws PdbException {
|
||||
private void getOrCreateEnum() {
|
||||
AbstractEnumMsType neededType = (AbstractEnumMsType) msType;
|
||||
if (dataType != null) {
|
||||
return;
|
||||
|
@ -218,8 +207,8 @@ public class EnumTypeApplier extends AbstractComplexTypeApplier {
|
|||
}
|
||||
}
|
||||
else {
|
||||
if (fwdRefApplier != null) {
|
||||
dataType = fwdRefApplier.getDataTypeInternal();
|
||||
if (forwardReferenceApplier != null) {
|
||||
dataType = forwardReferenceApplier.getDataTypeInternal();
|
||||
if (dataType != null) {
|
||||
return;
|
||||
}
|
||||
|
@ -275,19 +264,17 @@ public class EnumTypeApplier extends AbstractComplexTypeApplier {
|
|||
FieldListTypeApplier.getFieldListApplierSpecial(applicator, fieldListRecordNumber);
|
||||
|
||||
// Note: not doing anything with getNamespaceList() or getMethodsList() at this time.
|
||||
List<AbstractMsTypeApplier> memberList = fieldListApplier.getMemberList();
|
||||
List<MsTypeApplier> memberList = fieldListApplier.getMemberList();
|
||||
|
||||
int numElements = type.getNumElements();
|
||||
if (memberList.size() != numElements) {
|
||||
String message = "Enum expecting " + numElements + " elements, but only " +
|
||||
memberList.size() + " available for " + fullPathName;
|
||||
Msg.info(this, message);
|
||||
PdbLog.message(message);
|
||||
pdbLogAndInfoMessage(this, "Enum expecting " + numElements + " elements, but only " +
|
||||
memberList.size() + " available for " + fullPathName);
|
||||
}
|
||||
EnumDataType enumDataType = (EnumDataType) dataType;
|
||||
int length = getLength();
|
||||
boolean isSigned = isSigned();
|
||||
for (AbstractMsTypeApplier memberApplier : memberList) {
|
||||
for (MsTypeApplier memberApplier : memberList) {
|
||||
if (memberApplier instanceof EnumerateTypeApplier) {
|
||||
EnumerateTypeApplier enumerateApplier = (EnumerateTypeApplier) memberApplier;
|
||||
SymbolPath memberSymbolPath = new SymbolPath(enumerateApplier.getName());
|
||||
|
@ -297,7 +284,7 @@ public class EnumTypeApplier extends AbstractComplexTypeApplier {
|
|||
else { // (member instanceof AbstractMemberMsType)
|
||||
// I do not believe (until proven otherwise) that an Enum will have members of
|
||||
// type AbstractMemberMsType.
|
||||
PdbLog.message(getClass().getSimpleName() + ": unexpected " +
|
||||
pdbLogAndInfoMessage(this, getClass().getSimpleName() + ": unexpected " +
|
||||
memberApplier.getClass().getSimpleName());
|
||||
}
|
||||
}
|
||||
|
@ -310,7 +297,7 @@ public class EnumTypeApplier extends AbstractComplexTypeApplier {
|
|||
return 0;
|
||||
}
|
||||
if (!numeric.isIntegral()) {
|
||||
PdbLog.message("Using zero in place of non-integral enumerate: " + numeric);
|
||||
pdbLogAndInfoMessage(this, "Using zero in place of non-integral enumerate: " + numeric);
|
||||
return 0L; //
|
||||
}
|
||||
return numeric.getIntegral().longValue() & getMask();
|
||||
|
|
|
@ -19,47 +19,34 @@ import java.math.BigInteger;
|
|||
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.Numeric;
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.type.AbstractEnumerateMsType;
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.type.AbstractMsType;
|
||||
import ghidra.app.util.pdb.PdbNamespaceUtils;
|
||||
import ghidra.program.model.data.DataType;
|
||||
|
||||
/**
|
||||
* Applier for {@link AbstractEnumerateMsType} types.
|
||||
*/
|
||||
public class EnumerateTypeApplier extends AbstractMsTypeApplier {
|
||||
public class EnumerateTypeApplier extends MsTypeApplier {
|
||||
|
||||
private String fieldName;
|
||||
private Numeric numeric;
|
||||
|
||||
private static AbstractMsType validateType(AbstractMsType type)
|
||||
throws IllegalArgumentException {
|
||||
if (!(type instanceof AbstractEnumerateMsType)) {
|
||||
throw new IllegalArgumentException(
|
||||
"PDB Incorrectly applying " + type.getClass().getSimpleName() + " to " +
|
||||
EnumerateTypeApplier.class.getSimpleName());
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for enumerate type applier, for transforming a enumerate into a
|
||||
* Ghidra DataType.
|
||||
* Ghidra DataType.
|
||||
* @param applicator {@link PdbApplicator} for which this class is working.
|
||||
* @param msType {@link AbstractEnumerateMsType} to process.
|
||||
* @throws IllegalArgumentException Upon invalid arguments.
|
||||
*/
|
||||
public EnumerateTypeApplier(PdbApplicator applicator, AbstractMsType msType)
|
||||
throws IllegalArgumentException {
|
||||
super(applicator, validateType(msType));
|
||||
public EnumerateTypeApplier(PdbApplicator applicator, AbstractEnumerateMsType msType) {
|
||||
super(applicator, msType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BigInteger getSize() {
|
||||
BigInteger getSize() {
|
||||
return BigInteger.ZERO;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply() {
|
||||
void apply() {
|
||||
dataType = applyEnumerateMsType((AbstractEnumerateMsType) msType);
|
||||
// DataType dataType = applyEnumerateMsType((AbstractEnumerateMsType) msType);
|
||||
// ghDataType = dataType; // temporary while below is commented-out
|
||||
|
@ -67,11 +54,11 @@ public class EnumerateTypeApplier extends AbstractMsTypeApplier {
|
|||
// ghDataTypeDB = applicator.resolve(dataType);
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
String getName() {
|
||||
return fieldName;
|
||||
}
|
||||
|
||||
public Numeric getNumeric() {
|
||||
Numeric getNumeric() {
|
||||
return numeric;
|
||||
}
|
||||
|
||||
|
|
|
@ -22,24 +22,23 @@ import java.util.List;
|
|||
import ghidra.app.util.bin.format.pdb2.pdbreader.*;
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.type.*;
|
||||
import ghidra.program.model.data.DataType;
|
||||
import ghidra.util.Msg;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
|
||||
/**
|
||||
* Applier for {@link AbstractFieldListMsType} types and {@code NO_TYPE} when in place of the
|
||||
* former type.
|
||||
* former type.
|
||||
*/
|
||||
public class FieldListTypeApplier extends AbstractMsTypeApplier {
|
||||
public class FieldListTypeApplier extends MsTypeApplier {
|
||||
|
||||
private List<AbstractMsTypeApplier> baseClassList = new ArrayList<>();
|
||||
private List<AbstractMsTypeApplier> memberList = new ArrayList<>();
|
||||
private List<AbstractMsTypeApplier> methodList = new ArrayList<>();
|
||||
private List<MsTypeApplier> baseClassList = new ArrayList<>();
|
||||
private List<MsTypeApplier> memberList = new ArrayList<>();
|
||||
private List<MsTypeApplier> methodList = new ArrayList<>();
|
||||
private boolean isEmpty;
|
||||
|
||||
// return can be null
|
||||
static FieldListTypeApplier getFieldListApplierSpecial(PdbApplicator applicator,
|
||||
RecordNumber recordNumber) throws PdbException {
|
||||
AbstractMsTypeApplier applier =
|
||||
MsTypeApplier applier =
|
||||
applicator.getApplierOrNoTypeSpec(recordNumber, FieldListTypeApplier.class);
|
||||
FieldListTypeApplier fieldListApplier = null;
|
||||
if (applier instanceof FieldListTypeApplier) {
|
||||
|
@ -95,29 +94,29 @@ public class FieldListTypeApplier extends AbstractMsTypeApplier {
|
|||
* Indicates that the list is empty
|
||||
* @return {@code true} if list is empty.
|
||||
*/
|
||||
public boolean isEmpty() {
|
||||
boolean isEmpty() {
|
||||
return isEmpty;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BigInteger getSize() {
|
||||
BigInteger getSize() {
|
||||
return BigInteger.ZERO;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply() throws PdbException, CancelledException {
|
||||
void apply() throws PdbException, CancelledException {
|
||||
dataType = applyFieldListMsType((AbstractFieldListMsType) msType);
|
||||
}
|
||||
|
||||
public List<AbstractMsTypeApplier> getBaseClassList() {
|
||||
List<MsTypeApplier> getBaseClassList() {
|
||||
return baseClassList;
|
||||
}
|
||||
|
||||
public List<AbstractMsTypeApplier> getMemberList() {
|
||||
List<MsTypeApplier> getMemberList() {
|
||||
return memberList;
|
||||
}
|
||||
|
||||
public List<AbstractMsTypeApplier> getMethodList() {
|
||||
List<MsTypeApplier> getMethodList() {
|
||||
return methodList;
|
||||
}
|
||||
|
||||
|
@ -129,7 +128,7 @@ public class FieldListTypeApplier extends AbstractMsTypeApplier {
|
|||
applyMethods(type.getMethodList());
|
||||
|
||||
for (AbstractIndexMsType indexType : type.getIndexList()) {
|
||||
AbstractMsTypeApplier referencedTypeApplier =
|
||||
MsTypeApplier referencedTypeApplier =
|
||||
applicator.getTypeApplier(indexType.getReferencedRecordNumber());
|
||||
if (referencedTypeApplier instanceof FieldListTypeApplier) {
|
||||
FieldListTypeApplier subApplier = (FieldListTypeApplier) referencedTypeApplier;
|
||||
|
@ -138,9 +137,7 @@ public class FieldListTypeApplier extends AbstractMsTypeApplier {
|
|||
methodList.addAll(subApplier.getMethodList());
|
||||
}
|
||||
else {
|
||||
String message = "referenceTypeApplier is not FieldListTypeApplier";
|
||||
Msg.info(this, message);
|
||||
PdbLog.message(message);
|
||||
pdbLogAndInfoMessage(this, "referenceTypeApplier is not FieldListTypeApplier");
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
@ -150,7 +147,7 @@ public class FieldListTypeApplier extends AbstractMsTypeApplier {
|
|||
throws CancelledException, PdbException {
|
||||
for (MsTypeField typeIterated : baseClasses) {
|
||||
// Use dummy index of zero.
|
||||
AbstractMsTypeApplier applier =
|
||||
MsTypeApplier applier =
|
||||
applicator.getTypeApplier((AbstractMsType) typeIterated);
|
||||
applier.apply(); // Need to apply here, as these are embedded records
|
||||
baseClassList.add(applier);
|
||||
|
@ -160,7 +157,7 @@ public class FieldListTypeApplier extends AbstractMsTypeApplier {
|
|||
private void applyMembers(List<MsTypeField> members) throws CancelledException, PdbException {
|
||||
for (MsTypeField typeIterated : members) {
|
||||
// Use dummy index of zero.
|
||||
AbstractMsTypeApplier applier =
|
||||
MsTypeApplier applier =
|
||||
applicator.getTypeApplier((AbstractMsType) typeIterated);
|
||||
applier.apply(); // Need to apply here, as these are embedded records
|
||||
memberList.add(applier);
|
||||
|
@ -170,7 +167,7 @@ public class FieldListTypeApplier extends AbstractMsTypeApplier {
|
|||
private void applyMethods(List<MsTypeField> methods) throws CancelledException, PdbException {
|
||||
for (MsTypeField typeIterated : methods) {
|
||||
// Use dummy index of zero.
|
||||
AbstractMsTypeApplier applier =
|
||||
MsTypeApplier applier =
|
||||
applicator.getTypeApplier((AbstractMsType) typeIterated);
|
||||
// TODO: note that these are likely NoTypeAppliers at the moment, as we had not
|
||||
// yet implemented appliers for AbstractOneMethodMsType and
|
||||
|
|
|
@ -25,10 +25,15 @@ import ghidra.util.exception.CancelledException;
|
|||
/**
|
||||
* Applier for {@link ExtraFrameAndProcedureInformationMsSymbol} symbols.
|
||||
*/
|
||||
public class FrameAndProcedureInformationSymbolApplier extends AbstractMsSymbolApplier {
|
||||
public class FrameAndProcedureInformationSymbolApplier extends MsSymbolApplier {
|
||||
|
||||
private ExtraFrameAndProcedureInformationMsSymbol symbol;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param applicator the {@link PdbApplicator} for which we are working.
|
||||
* @param iter the Iterator containing the symbol sequence being processed
|
||||
*/
|
||||
public FrameAndProcedureInformationSymbolApplier(PdbApplicator applicator,
|
||||
AbstractMsSymbolIterator iter) {
|
||||
super(applicator, iter);
|
||||
|
@ -41,17 +46,15 @@ public class FrameAndProcedureInformationSymbolApplier extends AbstractMsSymbolA
|
|||
}
|
||||
|
||||
@Override
|
||||
public void applyTo(AbstractMsSymbolApplier applyToApplier)
|
||||
throws PdbException, CancelledException {
|
||||
void applyTo(MsSymbolApplier applyToApplier) throws PdbException, CancelledException {
|
||||
if (applyToApplier instanceof FunctionSymbolApplier) {
|
||||
FunctionSymbolApplier functionSymbolApplier = (FunctionSymbolApplier) applyToApplier;
|
||||
// public void applyTo(FunctionSymbolApplier functionSymbolApplier) {
|
||||
functionSymbolApplier.setSpecifiedFrameSize(symbol.getProcedureFrameTotalLength());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply() {
|
||||
void apply() {
|
||||
// Quietly do nothing
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,7 +37,7 @@ import ghidra.util.task.TaskMonitor;
|
|||
/**
|
||||
* Applier for {@link AbstractProcedureStartMsSymbol} and {@link AbstractThunkMsSymbol} symbols.
|
||||
*/
|
||||
public class FunctionSymbolApplier extends AbstractMsSymbolApplier {
|
||||
public class FunctionSymbolApplier extends MsSymbolApplier {
|
||||
|
||||
private static final String BLOCK_INDENT = " ";
|
||||
|
||||
|
@ -58,11 +58,17 @@ public class FunctionSymbolApplier extends AbstractMsSymbolApplier {
|
|||
|
||||
// private List<RegisterRelativeSymbolApplier> stackVariableAppliers = new ArrayList<>();
|
||||
|
||||
private List<AbstractMsSymbolApplier> allAppliers = new ArrayList<>();
|
||||
private List<MsSymbolApplier> allAppliers = new ArrayList<>();
|
||||
private RegisterChangeCalculator registerChangeCalculator;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param applicator the {@link PdbApplicator} for which we are working.
|
||||
* @param iter the Iterator containing the symbol sequence being processed
|
||||
* @throws CancelledException upon user cancellation
|
||||
*/
|
||||
public FunctionSymbolApplier(PdbApplicator applicator, AbstractMsSymbolIterator iter)
|
||||
throws CancelledException, NoSuchElementException {
|
||||
throws CancelledException {
|
||||
super(applicator, iter);
|
||||
AbstractMsSymbol abstractSymbol = iter.next();
|
||||
symbolBlockNestingLevel = 0;
|
||||
|
@ -71,11 +77,11 @@ public class FunctionSymbolApplier extends AbstractMsSymbolApplier {
|
|||
|
||||
if (abstractSymbol instanceof AbstractProcedureMsSymbol) {
|
||||
procedureSymbol = (AbstractProcedureMsSymbol) abstractSymbol;
|
||||
specifiedAddress = applicator.reladdr(procedureSymbol);
|
||||
specifiedAddress = applicator.getAddress(procedureSymbol);
|
||||
}
|
||||
else if (abstractSymbol instanceof AbstractThunkMsSymbol) {
|
||||
thunkSymbol = (AbstractThunkMsSymbol) abstractSymbol;
|
||||
specifiedAddress = applicator.reladdr(thunkSymbol);
|
||||
specifiedAddress = applicator.getAddress(thunkSymbol);
|
||||
}
|
||||
else {
|
||||
throw new AssertException(
|
||||
|
@ -86,14 +92,14 @@ public class FunctionSymbolApplier extends AbstractMsSymbolApplier {
|
|||
|
||||
while (notDone()) {
|
||||
applicator.checkCanceled();
|
||||
AbstractMsSymbolApplier applier = applicator.getSymbolApplier(iter);
|
||||
MsSymbolApplier applier = applicator.getSymbolApplier(iter);
|
||||
allAppliers.add(applier);
|
||||
applier.manageBlockNesting(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void manageBlockNesting(AbstractMsSymbolApplier applierParam) {
|
||||
void manageBlockNesting(MsSymbolApplier applierParam) {
|
||||
if (applierParam instanceof FunctionSymbolApplier) {
|
||||
FunctionSymbolApplier functionSymbolApplier = (FunctionSymbolApplier) applierParam;
|
||||
if (procedureSymbol != null) {
|
||||
|
@ -114,7 +120,7 @@ public class FunctionSymbolApplier extends AbstractMsSymbolApplier {
|
|||
* Returns the {@link Function} for this applier.
|
||||
* @return the Function
|
||||
*/
|
||||
public Function getFunction() {
|
||||
Function getFunction() {
|
||||
return function;
|
||||
}
|
||||
|
||||
|
@ -122,7 +128,7 @@ public class FunctionSymbolApplier extends AbstractMsSymbolApplier {
|
|||
* Returns the current frame size.
|
||||
* @return the current frame size.
|
||||
*/
|
||||
public long getCurrentFrameSize() {
|
||||
long getCurrentFrameSize() {
|
||||
return currentFrameSize;
|
||||
}
|
||||
|
||||
|
@ -130,7 +136,7 @@ public class FunctionSymbolApplier extends AbstractMsSymbolApplier {
|
|||
* Returns the frame size as specified by the PDB
|
||||
* @return the frame size.
|
||||
*/
|
||||
public long getSpecifiedFrameSize() {
|
||||
long getSpecifiedFrameSize() {
|
||||
return specifiedFrameSize;
|
||||
}
|
||||
|
||||
|
@ -147,7 +153,7 @@ public class FunctionSymbolApplier extends AbstractMsSymbolApplier {
|
|||
* Get the function name
|
||||
* @return the function name
|
||||
*/
|
||||
public String getName() {
|
||||
String getName() {
|
||||
if (procedureSymbol != null) {
|
||||
return procedureSymbol.getName();
|
||||
}
|
||||
|
@ -158,12 +164,12 @@ public class FunctionSymbolApplier extends AbstractMsSymbolApplier {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void applyTo(AbstractMsSymbolApplier applyToApplier) {
|
||||
void applyTo(MsSymbolApplier applyToApplier) {
|
||||
// Do nothing.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply() throws PdbException, CancelledException {
|
||||
void apply() throws PdbException, CancelledException {
|
||||
boolean result = applyTo(applicator.getCancelOnlyWrappingMonitor());
|
||||
if (result == false) {
|
||||
throw new PdbException("failure in applying " + this.getClass().getSimpleName() +
|
||||
|
@ -171,11 +177,11 @@ public class FunctionSymbolApplier extends AbstractMsSymbolApplier {
|
|||
}
|
||||
}
|
||||
|
||||
public boolean applyTo(TaskMonitor monitor) throws PdbException, CancelledException {
|
||||
boolean applyTo(TaskMonitor monitor) throws PdbException, CancelledException {
|
||||
return applyTo(applicator.getProgram(), remapAddress, monitor);
|
||||
}
|
||||
|
||||
public boolean applyTo(Program program, Address address, TaskMonitor monitor)
|
||||
boolean applyTo(Program program, Address address, TaskMonitor monitor)
|
||||
throws PdbException, CancelledException {
|
||||
|
||||
boolean functionSuccess = applyFunction(program, address, monitor);
|
||||
|
@ -186,7 +192,7 @@ public class FunctionSymbolApplier extends AbstractMsSymbolApplier {
|
|||
|
||||
baseParamOffset = VariableUtilities.getBaseStackParamOffset(function);
|
||||
|
||||
for (AbstractMsSymbolApplier applier : allAppliers) {
|
||||
for (MsSymbolApplier applier : allAppliers) {
|
||||
applier.applyTo(this);
|
||||
}
|
||||
|
||||
|
@ -202,11 +208,11 @@ public class FunctionSymbolApplier extends AbstractMsSymbolApplier {
|
|||
return true;
|
||||
}
|
||||
|
||||
public Integer getRegisterPrologChange(Register register) {
|
||||
Integer getRegisterPrologChange(Register register) {
|
||||
return registerChangeCalculator.getRegChange(applicator, register);
|
||||
}
|
||||
|
||||
public int getBaseParamOffset() {
|
||||
int getBaseParamOffset() {
|
||||
return baseParamOffset;
|
||||
}
|
||||
|
||||
|
@ -281,7 +287,7 @@ public class FunctionSymbolApplier extends AbstractMsSymbolApplier {
|
|||
}
|
||||
// Rest presumes procedureSymbol.
|
||||
RecordNumber typeRecordNumber = procedureSymbol.getTypeRecordNumber();
|
||||
AbstractMsTypeApplier applier = applicator.getTypeApplier(typeRecordNumber);
|
||||
MsTypeApplier applier = applicator.getTypeApplier(typeRecordNumber);
|
||||
if (applier == null) {
|
||||
applicator.appendLogMsg("Error: Failed to resolve datatype RecordNumber " +
|
||||
typeRecordNumber + " at " + address);
|
||||
|
@ -327,7 +333,7 @@ public class FunctionSymbolApplier extends AbstractMsSymbolApplier {
|
|||
return (symbolBlockNestingLevel > 0) && iter.hasNext();
|
||||
}
|
||||
|
||||
public int endBlock() {
|
||||
int endBlock() {
|
||||
if (--symbolBlockNestingLevel < 0) {
|
||||
applicator.appendLogMsg(
|
||||
"Block Nesting went negative for " + getName() + " at " + remapAddress);
|
||||
|
@ -338,7 +344,7 @@ public class FunctionSymbolApplier extends AbstractMsSymbolApplier {
|
|||
return symbolBlockNestingLevel;
|
||||
}
|
||||
|
||||
public void beginBlock(Address startAddress, String name, long length) {
|
||||
void beginBlock(Address startAddress, String name, long length) {
|
||||
|
||||
int nestingLevel = beginBlock(startAddress);
|
||||
if (!applicator.getPdbApplicatorOptions().applyCodeScopeBlockComments()) {
|
||||
|
@ -439,7 +445,7 @@ public class FunctionSymbolApplier extends AbstractMsSymbolApplier {
|
|||
return new CallDepthChangeInfo(function, scopeSet, frameReg, monitor);
|
||||
}
|
||||
|
||||
public Integer getRegChange(PdbApplicator applicator, Register register) {
|
||||
Integer getRegChange(PdbApplicator applicator, Register register) {
|
||||
if (callDepthChangeInfo == null || register == null) {
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -30,10 +30,16 @@ import ghidra.util.exception.CancelledException;
|
|||
/**
|
||||
* Applier for {@link AbstractLabelMsSymbol} symbols.
|
||||
*/
|
||||
public class LabelSymbolApplier extends AbstractMsSymbolApplier {
|
||||
public class LabelSymbolApplier extends MsSymbolApplier {
|
||||
|
||||
private AbstractLabelMsSymbol symbol;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param applicator the {@link PdbApplicator} for which we are working.
|
||||
* @param iter the Iterator containing the symbol sequence being processed
|
||||
* @throws CancelledException upon user cancellation
|
||||
*/
|
||||
public LabelSymbolApplier(PdbApplicator applicator, AbstractMsSymbolIterator iter) {
|
||||
super(applicator, iter);
|
||||
AbstractMsSymbol abstractSymbol = iter.next();
|
||||
|
@ -45,13 +51,13 @@ public class LabelSymbolApplier extends AbstractMsSymbolApplier {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void apply() throws PdbException, CancelledException {
|
||||
void apply() throws PdbException, CancelledException {
|
||||
if (!applicator.getPdbApplicatorOptions().applyInstructionLabels()) {
|
||||
return;
|
||||
}
|
||||
// Place compiler generated symbols (e.g., $LN9) within containing function when possible
|
||||
String name = symbol.getName();
|
||||
Address symbolAddress = applicator.reladdr(symbol);
|
||||
Address symbolAddress = applicator.getAddress(symbol);
|
||||
FunctionManager functionManager = applicator.getProgram().getFunctionManager();
|
||||
// TODO: What do we do with labels such as this?... "__catch$?test_eh1@@YAHXZ$7"
|
||||
if (name.startsWith("$") && !name.contains(Namespace.DELIMITER)) {
|
||||
|
@ -67,7 +73,7 @@ public class LabelSymbolApplier extends AbstractMsSymbolApplier {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void applyTo(AbstractMsSymbolApplier applyToApplier) {
|
||||
void applyTo(MsSymbolApplier applyToApplier) {
|
||||
// Do nothing
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,20 +16,23 @@
|
|||
package ghidra.app.util.pdb.pdbapplicator;
|
||||
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.PdbException;
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.PdbLog;
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.symbol.*;
|
||||
import ghidra.app.util.pdb.pdbapplicator.SymbolGroup.AbstractMsSymbolIterator;
|
||||
import ghidra.util.Msg;
|
||||
import ghidra.util.exception.AssertException;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
|
||||
/**
|
||||
* Applier for {@link AbstractLocalSymbolInOptimizedCodeMsSymbol} symbols.
|
||||
*/
|
||||
public class LocalOptimizedSymbolApplier extends AbstractMsSymbolApplier {
|
||||
public class LocalOptimizedSymbolApplier extends MsSymbolApplier {
|
||||
|
||||
private AbstractLocalSymbolInOptimizedCodeMsSymbol symbol;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param applicator the {@link PdbApplicator} for which we are working.
|
||||
* @param iter the Iterator containing the symbol sequence being processed
|
||||
*/
|
||||
public LocalOptimizedSymbolApplier(PdbApplicator applicator, AbstractMsSymbolIterator iter) {
|
||||
super(applicator, iter);
|
||||
AbstractMsSymbol abstractSymbol = iter.next();
|
||||
|
@ -41,15 +44,13 @@ public class LocalOptimizedSymbolApplier extends AbstractMsSymbolApplier {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void apply() throws PdbException, CancelledException {
|
||||
String message = "Cannot apply " + this.getClass().getSimpleName() + " directly to program";
|
||||
Msg.info(this, message);
|
||||
PdbLog.message(message);
|
||||
void apply() throws PdbException, CancelledException {
|
||||
pdbLogAndInfoMessage(this,
|
||||
"Cannot apply " + this.getClass().getSimpleName() + " directly to program");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyTo(AbstractMsSymbolApplier applyToApplier)
|
||||
throws PdbException, CancelledException {
|
||||
void applyTo(MsSymbolApplier applyToApplier) throws PdbException, CancelledException {
|
||||
if (!applicator.getPdbApplicatorOptions().applyFunctionVariables()) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -20,7 +20,8 @@ import java.math.BigInteger;
|
|||
import ghidra.app.util.SymbolPath;
|
||||
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.app.util.bin.format.pdb2.pdbreader.type.AbstractMemberFunctionMsType;
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.type.CallingConvention;
|
||||
import ghidra.program.model.data.DataType;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
|
||||
|
@ -29,34 +30,22 @@ import ghidra.util.exception.CancelledException;
|
|||
*/
|
||||
public class MemberFunctionTypeApplier extends AbstractFunctionTypeApplier {
|
||||
|
||||
// private boolean hasThisPointer = false;
|
||||
private AbstractMsTypeApplier thisPointerApplier = null;
|
||||
private CompositeTypeApplier containingCompositeApplier = null;
|
||||
|
||||
private static AbstractMsType validateType(AbstractMsType type)
|
||||
throws IllegalArgumentException {
|
||||
if (!(type instanceof AbstractMemberFunctionMsType)) {
|
||||
throw new IllegalArgumentException(
|
||||
"PDB Incorrectly applying " + type.getClass().getSimpleName() + " to " +
|
||||
MemberFunctionTypeApplier.class.getSimpleName());
|
||||
}
|
||||
return type;
|
||||
}
|
||||
private MsTypeApplier thisPointerApplier = null;
|
||||
|
||||
/**
|
||||
* Constructor for the applicator that applies {@link AbstractMemberFunctionMsType},
|
||||
* transforming it into a Ghidra {@link DataType}.
|
||||
* transforming it into a Ghidra {@link DataType}.
|
||||
* @param applicator {@link PdbApplicator} for which this class is working.
|
||||
* @param msType {@link AbstractMemberFunctionMsType} to processes.
|
||||
* @throws IllegalArgumentException Upon type mismatch.
|
||||
*/
|
||||
public MemberFunctionTypeApplier(PdbApplicator applicator, AbstractMsType msType)
|
||||
public MemberFunctionTypeApplier(PdbApplicator applicator, AbstractMemberFunctionMsType msType)
|
||||
throws IllegalArgumentException {
|
||||
super(applicator, validateType(msType));
|
||||
super(applicator, msType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BigInteger getSize() {
|
||||
BigInteger getSize() {
|
||||
return BigInteger.ZERO;
|
||||
}
|
||||
|
||||
|
@ -66,8 +55,8 @@ public class MemberFunctionTypeApplier extends AbstractFunctionTypeApplier {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected boolean hasThisPointer() throws CancelledException, PdbException {
|
||||
AbstractMsTypeApplier applier = applicator.getTypeApplier(
|
||||
protected boolean hasThisPointer() {
|
||||
MsTypeApplier applier = applicator.getTypeApplier(
|
||||
((AbstractMemberFunctionMsType) msType).getThisPointerRecordNumber());
|
||||
if ((applier instanceof PrimitiveTypeApplier &&
|
||||
((PrimitiveTypeApplier) applier).isNoType())) {
|
||||
|
@ -87,7 +76,7 @@ public class MemberFunctionTypeApplier extends AbstractFunctionTypeApplier {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void apply() throws PdbException, CancelledException {
|
||||
void apply() throws PdbException, CancelledException {
|
||||
predefineClasses();
|
||||
applyFunction(getCallingConvention(), hasThisPointer());
|
||||
}
|
||||
|
@ -99,7 +88,7 @@ public class MemberFunctionTypeApplier extends AbstractFunctionTypeApplier {
|
|||
applicator.getPdbApplicatorMetrics().witnessMemberFunctionThisPointer(
|
||||
thisPointerApplier);
|
||||
if (thisPointerApplier instanceof PointerTypeApplier) {
|
||||
AbstractMsTypeApplier underlyingApplier =
|
||||
MsTypeApplier underlyingApplier =
|
||||
getThisUnderlyingApplier((PointerTypeApplier) thisPointerApplier);
|
||||
applicator.getPdbApplicatorMetrics().witnessMemberFunctionThisPointerUnderlyingType(
|
||||
underlyingApplier);
|
||||
|
@ -185,8 +174,8 @@ public class MemberFunctionTypeApplier extends AbstractFunctionTypeApplier {
|
|||
// return true;
|
||||
// }
|
||||
|
||||
private AbstractMsTypeApplier getThisPointerApplier(AbstractMemberFunctionMsType procType) {
|
||||
AbstractMsTypeApplier applier =
|
||||
private MsTypeApplier getThisPointerApplier(AbstractMemberFunctionMsType procType) {
|
||||
MsTypeApplier applier =
|
||||
applicator.getTypeApplier(procType.getThisPointerRecordNumber());
|
||||
|
||||
// if ((applier instanceof PrimitiveTypeApplier &&
|
||||
|
@ -204,7 +193,7 @@ public class MemberFunctionTypeApplier extends AbstractFunctionTypeApplier {
|
|||
return applier;
|
||||
}
|
||||
|
||||
private AbstractMsTypeApplier getThisUnderlyingApplier(PointerTypeApplier thisApplier) {
|
||||
private MsTypeApplier getThisUnderlyingApplier(PointerTypeApplier thisApplier) {
|
||||
return thisApplier.getUnmodifiedUnderlyingTypeApplier();
|
||||
}
|
||||
|
||||
|
|
|
@ -18,42 +18,32 @@ package ghidra.app.util.pdb.pdbapplicator;
|
|||
import java.math.BigInteger;
|
||||
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.PdbException;
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.type.*;
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.type.AbstractMemberMsType;
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.type.ClassFieldMsAttributes;
|
||||
import ghidra.program.model.data.DataType;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
|
||||
/**
|
||||
* Applier for {@link AbstractMemberMsType} types.
|
||||
*/
|
||||
public class MemberTypeApplier extends AbstractMsTypeApplier {
|
||||
|
||||
private static AbstractMsType validateType(AbstractMsType type)
|
||||
throws IllegalArgumentException {
|
||||
if (!(type instanceof AbstractMemberMsType)) {
|
||||
throw new IllegalArgumentException("PDB Incorrectly applying " +
|
||||
type.getClass().getSimpleName() + " to " + MemberTypeApplier.class.getSimpleName());
|
||||
}
|
||||
return type;
|
||||
}
|
||||
public class MemberTypeApplier extends MsTypeApplier {
|
||||
|
||||
/**
|
||||
* Constructor for member type applier.
|
||||
* @param applicator {@link PdbApplicator} for which this class is working.
|
||||
* @param msType {@link AbstractMemberMsType} to process.
|
||||
* @throws IllegalArgumentException Upon invalid arguments.
|
||||
*/
|
||||
public MemberTypeApplier(PdbApplicator applicator, AbstractMsType msType)
|
||||
throws IllegalArgumentException {
|
||||
super(applicator, validateType(msType));
|
||||
public MemberTypeApplier(PdbApplicator applicator, AbstractMemberMsType msType) {
|
||||
super(applicator, msType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BigInteger getSize() {
|
||||
BigInteger getSize() {
|
||||
return BigInteger.ZERO;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply() throws PdbException, CancelledException {
|
||||
void apply() throws PdbException, CancelledException {
|
||||
dataType = applyMemberMsType((AbstractMemberMsType) msType);
|
||||
// DataType dataType = applyMemberMsType((AbstractMemberMsType) msType);
|
||||
// ghDataType = dataType; // temporary while below is commented-out
|
||||
|
@ -61,20 +51,21 @@ public class MemberTypeApplier extends AbstractMsTypeApplier {
|
|||
// ghDataTypeDB = applicator.resolve(dataType);
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
String getName() {
|
||||
return ((AbstractMemberMsType) msType).getName();
|
||||
}
|
||||
|
||||
public BigInteger getOffset() {
|
||||
BigInteger getOffset() {
|
||||
return ((AbstractMemberMsType) msType).getOffset();
|
||||
}
|
||||
|
||||
public ClassFieldMsAttributes getAttribute() {
|
||||
ClassFieldMsAttributes getAttribute() {
|
||||
return ((AbstractMemberMsType) msType).getAttribute();
|
||||
}
|
||||
|
||||
public AbstractMsTypeApplier getFieldTypeApplier() {
|
||||
return applicator.getTypeApplier(((AbstractMemberMsType) msType).getFieldTypeRecordNumber());
|
||||
MsTypeApplier getFieldTypeApplier() {
|
||||
return applicator.getTypeApplier(
|
||||
((AbstractMemberMsType) msType).getFieldTypeRecordNumber());
|
||||
}
|
||||
|
||||
private DataType applyMemberMsType(AbstractMemberMsType type) {
|
||||
|
@ -91,7 +82,6 @@ public class MemberTypeApplier extends AbstractMsTypeApplier {
|
|||
//// DataType fieldDataType = getConvertedDataType(applicator, fieldTypeIndex);
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -19,51 +19,26 @@ import java.math.BigInteger;
|
|||
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.PdbException;
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.type.AbstractModifierMsType;
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.type.AbstractMsType;
|
||||
import ghidra.program.model.data.DataType;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
|
||||
/**
|
||||
* Applier for {@link AbstractModifierMsType} types.
|
||||
*/
|
||||
//public class ModifierTypeApplier extends AbstractMsTypeApplier {
|
||||
public class ModifierTypeApplier extends AbstractMsTypeApplier {
|
||||
public class ModifierTypeApplier extends MsTypeApplier {
|
||||
|
||||
private boolean isDeferred = false;
|
||||
|
||||
private AbstractMsTypeApplier modifiedTypeApplier = null;
|
||||
|
||||
private static AbstractMsType validateType(AbstractMsType type)
|
||||
throws IllegalArgumentException {
|
||||
if (!(type instanceof AbstractModifierMsType)) {
|
||||
throw new IllegalArgumentException(
|
||||
"PDB Incorrectly applying " + type.getClass().getSimpleName() + " to " +
|
||||
ModifierTypeApplier.class.getSimpleName());
|
||||
}
|
||||
return type;
|
||||
}
|
||||
private MsTypeApplier modifiedTypeApplier = null;
|
||||
|
||||
/**
|
||||
* Constructor for modifier type applier.
|
||||
* @param applicator {@link PdbApplicator} for which this class is working.
|
||||
* @param msType {@link AbstractModifierMsType} to processes.
|
||||
* @throws IllegalArgumentException Upon invalid arguments.
|
||||
*/
|
||||
public ModifierTypeApplier(PdbApplicator applicator, AbstractMsType msType)
|
||||
throws IllegalArgumentException {
|
||||
super(applicator, validateType(msType));
|
||||
public ModifierTypeApplier(PdbApplicator applicator, AbstractModifierMsType msType) {
|
||||
super(applicator, msType);
|
||||
}
|
||||
|
||||
//==============================================================================================
|
||||
public void setDeferred() {
|
||||
isDeferred = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDeferred() {
|
||||
return isDeferred;
|
||||
}
|
||||
|
||||
@Override
|
||||
void deferredApply() throws PdbException, CancelledException {
|
||||
// Do nothing. Already applied. Just needs late resolve
|
||||
|
@ -71,7 +46,7 @@ public class ModifierTypeApplier extends AbstractMsTypeApplier {
|
|||
|
||||
//==============================================================================================
|
||||
@Override
|
||||
public BigInteger getSize() {
|
||||
BigInteger getSize() {
|
||||
if (modifiedTypeApplier == null) {
|
||||
return BigInteger.ZERO;
|
||||
}
|
||||
|
@ -79,7 +54,7 @@ public class ModifierTypeApplier extends AbstractMsTypeApplier {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void apply() throws PdbException, CancelledException {
|
||||
void apply() throws PdbException, CancelledException {
|
||||
// dataType = applyModifierMsType((AbstractModifierMsType) msType);
|
||||
applyOrDeferForDependencies();
|
||||
}
|
||||
|
@ -87,8 +62,7 @@ public class ModifierTypeApplier extends AbstractMsTypeApplier {
|
|||
private void applyOrDeferForDependencies() {
|
||||
AbstractModifierMsType type = (AbstractModifierMsType) msType;
|
||||
applyModifierMsType(type);
|
||||
AbstractMsTypeApplier modifiedApplier =
|
||||
applicator.getTypeApplier(type.getModifiedRecordNumber());
|
||||
MsTypeApplier modifiedApplier = applicator.getTypeApplier(type.getModifiedRecordNumber());
|
||||
if (modifiedApplier.isDeferred()) {
|
||||
applicator.addApplierDependency(this, modifiedApplier);
|
||||
setDeferred();
|
||||
|
@ -100,7 +74,7 @@ public class ModifierTypeApplier extends AbstractMsTypeApplier {
|
|||
}
|
||||
|
||||
@Override
|
||||
public DataType getDataType() {
|
||||
DataType getDataType() {
|
||||
return modifiedTypeApplier.getDataType();
|
||||
}
|
||||
|
||||
|
@ -130,7 +104,7 @@ public class ModifierTypeApplier extends AbstractMsTypeApplier {
|
|||
return modifiedTypeApplier.getCycleBreakType();
|
||||
}
|
||||
|
||||
public AbstractMsTypeApplier getModifiedTypeApplier() {
|
||||
MsTypeApplier getModifiedTypeApplier() {
|
||||
return modifiedTypeApplier;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,17 +17,31 @@ package ghidra.app.util.pdb.pdbapplicator;
|
|||
|
||||
import java.util.Objects;
|
||||
|
||||
import ghidra.app.plugin.processors.sleigh.symbol.Symbol;
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.PdbException;
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.PdbLog;
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.symbol.AbstractMsSymbol;
|
||||
import ghidra.app.util.pdb.pdbapplicator.SymbolGroup.AbstractMsSymbolIterator;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
|
||||
public abstract class AbstractMsSymbolApplier {
|
||||
/**
|
||||
* Abstract class representing the applier for a specific {@link AbstractMsSymbol}. The
|
||||
* {@link #apply()} method creates an associated {@link Symbol}, if applicable, or might
|
||||
* apply information to other {@link MsSymbolApplier AbstractMsSymbolAppliers}.
|
||||
* Methods associated with the {@link MsSymbolApplier} or derived class will
|
||||
* make fields available to the user from the {@link AbstractMsSymbol}.
|
||||
*/
|
||||
public abstract class MsSymbolApplier {
|
||||
protected PdbApplicator applicator;
|
||||
protected AbstractMsSymbolIterator iter;
|
||||
protected long currentOffset;
|
||||
|
||||
public AbstractMsSymbolApplier(PdbApplicator applicator, AbstractMsSymbolIterator iter) {
|
||||
/**
|
||||
* Constructor
|
||||
* @param applicator the {@link PdbApplicator} for which we are working.
|
||||
* @param iter the Iterator containing the symbol sequence being processed
|
||||
*/
|
||||
public MsSymbolApplier(PdbApplicator applicator, AbstractMsSymbolIterator iter) {
|
||||
Objects.requireNonNull(applicator, "applicator cannot be null");
|
||||
Objects.requireNonNull(iter, "symbolGroup cannot be null");
|
||||
this.applicator = applicator;
|
||||
|
@ -35,6 +49,15 @@ public abstract class AbstractMsSymbolApplier {
|
|||
currentOffset = iter.getCurrentOffset();
|
||||
}
|
||||
|
||||
/**
|
||||
* Puts message to {@link PdbLog} and to Msg.info()
|
||||
* @param originator a Logger instance, "this", or YourClass.class
|
||||
* @param message the message to display
|
||||
*/
|
||||
protected void pdbLogAndInfoMessage(Object originator, String message) {
|
||||
applicator.pdbLogAndInfoMessage(originator, message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the offset of the {@link SymbolGroup} back to the state when this applicator was
|
||||
* created.
|
||||
|
@ -49,26 +72,26 @@ public abstract class AbstractMsSymbolApplier {
|
|||
* @throws PdbException if there was a problem processing the data.
|
||||
* @throws CancelledException upon user cancellation
|
||||
*/
|
||||
public abstract void apply() throws PdbException, CancelledException;
|
||||
abstract void apply() throws PdbException, CancelledException;
|
||||
|
||||
/**
|
||||
* Applies logic of this class to another {@link AbstractMsSymbolApplier} instead of to
|
||||
* "the program."
|
||||
* Applies logic of this class to another {@link MsSymbolApplier} instead of to
|
||||
* "the program."
|
||||
* @param applyToApplier the applier to which the logic of this class is applied.
|
||||
* @throws PdbException if there was a problem processing the data.
|
||||
* @throws CancelledException upon user cancellation.
|
||||
*/
|
||||
public abstract void applyTo(AbstractMsSymbolApplier applyToApplier)
|
||||
abstract void applyTo(MsSymbolApplier applyToApplier)
|
||||
throws PdbException, CancelledException;
|
||||
|
||||
/**
|
||||
* Manages block nesting for symbols/appliers that represent the beginning or end of blocks.
|
||||
* The default is to do nothing. Otherwise the appliers should implement the appropriate
|
||||
* logic.
|
||||
* The default is to do nothing. Otherwise the appliers should implement the appropriate
|
||||
* logic.
|
||||
* @param applierParam the applier which is managing blocks, which is typically
|
||||
* {@link FunctionSymbolApplier}.
|
||||
* {@link FunctionSymbolApplier}.
|
||||
*/
|
||||
public void manageBlockNesting(AbstractMsSymbolApplier applierParam) {
|
||||
void manageBlockNesting(MsSymbolApplier applierParam) {
|
||||
// Do nothing by default.
|
||||
}
|
||||
|
|
@ -18,20 +18,19 @@ package ghidra.app.util.pdb.pdbapplicator;
|
|||
import java.math.BigInteger;
|
||||
import java.util.*;
|
||||
|
||||
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.*;
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.type.AbstractMsType;
|
||||
import ghidra.program.model.data.DataType;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
|
||||
/**
|
||||
* Abstract class representing the applier/wrapper for a specific {@link AbstractMsType}. The
|
||||
* {link {@link #apply()} method creates an associated {@link DataType}, if
|
||||
* applicable. Methods associated with the {@link AbstractMsTypeApplier} or derived class will
|
||||
* make fields available to the user, first by trying to get them from the {@link DataType},
|
||||
* otherwise getting them from the {@link AbstractMsType}.
|
||||
* Abstract class representing the applier for a specific {@link AbstractMsType}. The
|
||||
* {@link #apply()} method creates an associated {@link DataType}, if applicable.
|
||||
* Methods associated with the {@link MsTypeApplier} or derived class will
|
||||
* make fields available to the user, first by trying to get them from the {@link DataType},
|
||||
* otherwise getting them from the {@link AbstractMsType}.
|
||||
*/
|
||||
public abstract class AbstractMsTypeApplier implements Comparable<AbstractMsTypeApplier> {
|
||||
public abstract class MsTypeApplier {
|
||||
|
||||
protected PdbApplicator applicator;
|
||||
protected AbstractMsType msType;
|
||||
|
@ -43,19 +42,16 @@ public abstract class AbstractMsTypeApplier implements Comparable<AbstractMsType
|
|||
protected boolean resolved = false;
|
||||
protected boolean applied = false;
|
||||
|
||||
protected Set<AbstractMsTypeApplier> waitSet = new HashSet<>();
|
||||
private boolean isDeferred = false;
|
||||
|
||||
protected Set<MsTypeApplier> waitSet = new HashSet<>();
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* @param applicator {@link PdbApplicator} for which this class is working.
|
||||
* @param msType {@link AbstractMsType} to apply.
|
||||
* @throws IllegalArgumentException Upon invalid arguments.
|
||||
*/
|
||||
public AbstractMsTypeApplier(PdbApplicator applicator, AbstractMsType msType)
|
||||
throws IllegalArgumentException {
|
||||
if (msType == null) {
|
||||
throw new IllegalArgumentException("PDB Type Applying null AbstractMsType");
|
||||
}
|
||||
public MsTypeApplier(PdbApplicator applicator, AbstractMsType msType) {
|
||||
this.applicator = applicator;
|
||||
this.msType = msType;
|
||||
RecordNumber recordNumber = msType.getRecordNumber();
|
||||
|
@ -68,30 +64,74 @@ public abstract class AbstractMsTypeApplier implements Comparable<AbstractMsType
|
|||
dataType = null;
|
||||
}
|
||||
|
||||
public boolean isApplied() {
|
||||
/**
|
||||
* Puts message to {@link PdbLog} and to Msg.info()
|
||||
* @param originator a Logger instance, "this", or YourClass.class
|
||||
* @param message the message to display
|
||||
*/
|
||||
protected void pdbLogAndInfoMessage(Object originator, String message) {
|
||||
applicator.pdbLogAndInfoMessage(originator, message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if the type has been applied
|
||||
* @return {@code true} if applied.
|
||||
*/
|
||||
boolean isApplied() {
|
||||
return applied;
|
||||
}
|
||||
|
||||
public void setApplied() {
|
||||
/**
|
||||
* Sets the {@code applied} flag to {@code true}
|
||||
*/
|
||||
void setApplied() {
|
||||
applied = true;
|
||||
}
|
||||
|
||||
boolean isDeferred() {
|
||||
return false;
|
||||
/**
|
||||
* Sets the isDeferred flag to indicate that the application of the information should be
|
||||
* done when the {@link @deferredApply()} method is called
|
||||
*/
|
||||
void setDeferred() {
|
||||
isDeferred = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if the application as been deferred (during the {@link #apply()}
|
||||
* method. The {@link #deferredApply()} method will need to be applied at the appropriate
|
||||
* place in the processing sequence (depending on data dependency ordering) as determined
|
||||
* and driven by the {@link PdbApplicator}.
|
||||
* @return {@code true} if application was deferred
|
||||
*/
|
||||
boolean isDeferred() {
|
||||
return isDeferred;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs the work required in a deferred application of the data type. This method
|
||||
* is used by the {@link PdbApplicator} in the correct data dependency sequence.
|
||||
* @throws PdbException on error applying the data type
|
||||
* @throws CancelledException on user cancellation
|
||||
*/
|
||||
void deferredApply() throws PdbException, CancelledException {
|
||||
// default is to do nothing, as most appliers are not deferrable (or should not be).
|
||||
}
|
||||
|
||||
public AbstractMsTypeApplier getDependencyApplier() {
|
||||
/**
|
||||
* Returns the applier for this type that needs to be called when the data type is processed
|
||||
* in dependency order. This will usually return "this," except in cases where there can be
|
||||
* forward references and definition appliers for the same type.
|
||||
* @return the applier to be used for doing the real applier work when dependency order
|
||||
* matters.
|
||||
*/
|
||||
MsTypeApplier getDependencyApplier() {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves the type through the DataTypeManager and makes the resolved type primary.
|
||||
*/
|
||||
public void resolve() {
|
||||
void resolve() {
|
||||
if (resolved) {
|
||||
return;
|
||||
}
|
||||
|
@ -105,7 +145,7 @@ public abstract class AbstractMsTypeApplier implements Comparable<AbstractMsType
|
|||
* Returns the {@link AbstractMsType} associated with this applier/wrapper.
|
||||
* @return {@link AbstractMsType} associated with this applier/wrapper.
|
||||
*/
|
||||
public AbstractMsType getMsType() {
|
||||
AbstractMsType getMsType() {
|
||||
return msType;
|
||||
}
|
||||
|
||||
|
@ -113,7 +153,7 @@ public abstract class AbstractMsTypeApplier implements Comparable<AbstractMsType
|
|||
* Returns the {@link DataType} associated with this applier/wrapper.
|
||||
* @return {@link DataType} associated with this applier/wrapper.
|
||||
*/
|
||||
public DataType getDataType() {
|
||||
DataType getDataType() {
|
||||
if (resolved) {
|
||||
return resolvedDataType;
|
||||
}
|
||||
|
@ -134,19 +174,19 @@ public abstract class AbstractMsTypeApplier implements Comparable<AbstractMsType
|
|||
* @throws PdbException if there was a problem processing the data.
|
||||
* @throws CancelledException upon user cancellation
|
||||
*/
|
||||
public abstract void apply() throws PdbException, CancelledException;
|
||||
abstract void apply() throws PdbException, CancelledException;
|
||||
|
||||
/**
|
||||
* Returns the size of the type or 0 if unknown.
|
||||
* @return the size; zero if unknown.
|
||||
*/
|
||||
public abstract BigInteger getSize();
|
||||
abstract BigInteger getSize();
|
||||
|
||||
/**
|
||||
* Returns the (long) size of the type or 0 if unknown. Or Long.MAX_VALUE if too large.
|
||||
* @return the size; zero if unknown.
|
||||
*/
|
||||
public long getSizeLong() {
|
||||
long getSizeLong() {
|
||||
return PdbApplicator.bigIntegerToLong(applicator, getSize());
|
||||
}
|
||||
|
||||
|
@ -154,7 +194,7 @@ public abstract class AbstractMsTypeApplier implements Comparable<AbstractMsType
|
|||
* Returns the (int) size of the type or 0 if unknown. Or Integer.MAX_VALUE if too large.
|
||||
* @return the size; zero if unknown.
|
||||
*/
|
||||
public int getSizeInt() {
|
||||
int getSizeInt() {
|
||||
return PdbApplicator.bigIntegerToInt(applicator, getSize());
|
||||
}
|
||||
|
||||
|
@ -183,7 +223,7 @@ public abstract class AbstractMsTypeApplier implements Comparable<AbstractMsType
|
|||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
AbstractMsTypeApplier other = (AbstractMsTypeApplier) obj;
|
||||
MsTypeApplier other = (MsTypeApplier) obj;
|
||||
if (index != other.index) {
|
||||
return false;
|
||||
}
|
||||
|
@ -193,17 +233,11 @@ public abstract class AbstractMsTypeApplier implements Comparable<AbstractMsType
|
|||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(AbstractMsTypeApplier o) {
|
||||
int val = hashCode() - o.hashCode();
|
||||
return val;
|
||||
}
|
||||
|
||||
protected void waitSetPut(AbstractMsTypeApplier applier) {
|
||||
protected void waitSetPut(MsTypeApplier applier) {
|
||||
waitSet.add(applier);
|
||||
}
|
||||
|
||||
protected boolean waitSetRemove(AbstractMsTypeApplier applier) {
|
||||
protected boolean waitSetRemove(MsTypeApplier applier) {
|
||||
return waitSet.remove(applier);
|
||||
}
|
||||
|
||||
|
@ -211,8 +245,8 @@ public abstract class AbstractMsTypeApplier implements Comparable<AbstractMsType
|
|||
return waitSet.isEmpty();
|
||||
}
|
||||
|
||||
protected AbstractMsTypeApplier waitSetGetNext() {
|
||||
List<AbstractMsTypeApplier> list = new ArrayList<>(waitSet);
|
||||
protected MsTypeApplier waitSetGetNext() {
|
||||
List<MsTypeApplier> list = new ArrayList<>(waitSet);
|
||||
return list.get(0);
|
||||
}
|
||||
|
|
@ -26,8 +26,8 @@ import ghidra.util.exception.CancelledException;
|
|||
/**
|
||||
* Applier for {@link AbstractNestedTypeMsType} and {@link AbstractNestedTypeExtMsType} types.
|
||||
*/
|
||||
public class NestedTypeApplier extends AbstractMsTypeApplier {
|
||||
private AbstractMsTypeApplier nestedTypeDefinitionApplier = null;
|
||||
public class NestedTypeApplier extends MsTypeApplier {
|
||||
private MsTypeApplier nestedTypeDefinitionApplier = null;
|
||||
|
||||
private static AbstractMsType validateType(AbstractMsType type)
|
||||
throws IllegalArgumentException {
|
||||
|
@ -52,7 +52,7 @@ public class NestedTypeApplier extends AbstractMsTypeApplier {
|
|||
}
|
||||
|
||||
@Override
|
||||
public BigInteger getSize() {
|
||||
BigInteger getSize() {
|
||||
if (nestedTypeDefinitionApplier == null) {
|
||||
return BigInteger.ZERO;
|
||||
}
|
||||
|
@ -63,7 +63,7 @@ public class NestedTypeApplier extends AbstractMsTypeApplier {
|
|||
* Returns the name of this nested type.
|
||||
* @return Name of the nested type.
|
||||
*/
|
||||
public String getTypeName() {
|
||||
String getTypeName() {
|
||||
if (nestedTypeDefinitionApplier == null) {
|
||||
return "";
|
||||
}
|
||||
|
@ -74,7 +74,7 @@ public class NestedTypeApplier extends AbstractMsTypeApplier {
|
|||
* Returns the nested (member?) name for this nested type.
|
||||
* @return (Member?) Name for the nested type.
|
||||
*/
|
||||
public String getMemberName() {
|
||||
String getMemberName() {
|
||||
if (nestedTypeDefinitionApplier == null) {
|
||||
return "";
|
||||
}
|
||||
|
@ -84,7 +84,7 @@ public class NestedTypeApplier extends AbstractMsTypeApplier {
|
|||
return ((AbstractNestedTypeExtMsType) msType).getName();
|
||||
}
|
||||
|
||||
AbstractMsTypeApplier getNestedTypeDefinitionApplier() {
|
||||
MsTypeApplier getNestedTypeDefinitionApplier() {
|
||||
return applicator.getTypeApplier(getNestedTypeDefinitionRecordNumber());
|
||||
}
|
||||
|
||||
|
@ -99,7 +99,7 @@ public class NestedTypeApplier extends AbstractMsTypeApplier {
|
|||
* Indicates if there are attributes. Returns false if not "applied" yet.
|
||||
* @return [@code true} if there are attributes.
|
||||
*/
|
||||
public boolean hasAttributes() {
|
||||
boolean hasAttributes() {
|
||||
if (nestedTypeDefinitionApplier == null) {
|
||||
return false;
|
||||
}
|
||||
|
@ -113,7 +113,7 @@ public class NestedTypeApplier extends AbstractMsTypeApplier {
|
|||
* Returns the attributes if they exist.
|
||||
* @return the attributes or null if they do not exist.
|
||||
*/
|
||||
public ClassFieldMsAttributes getAttributes() {
|
||||
ClassFieldMsAttributes getAttributes() {
|
||||
AbstractMsType type = nestedTypeDefinitionApplier.getMsType();
|
||||
if (type instanceof AbstractNestedTypeExtMsType) {
|
||||
return ((AbstractNestedTypeExtMsType) type).getClassFieldAttributes();
|
||||
|
@ -122,7 +122,7 @@ public class NestedTypeApplier extends AbstractMsTypeApplier {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void apply() throws PdbException, CancelledException {
|
||||
void apply() throws PdbException, CancelledException {
|
||||
if (msType instanceof AbstractNestedTypeMsType) {
|
||||
dataType = applyNestedTypeMsType((AbstractNestedTypeMsType) msType);
|
||||
}
|
||||
|
@ -132,12 +132,14 @@ public class NestedTypeApplier extends AbstractMsTypeApplier {
|
|||
}
|
||||
|
||||
private DataType applyNestedTypeMsType(AbstractNestedTypeMsType type) {
|
||||
nestedTypeDefinitionApplier = applicator.getTypeApplier(type.getNestedTypeDefinitionRecordNumber());
|
||||
nestedTypeDefinitionApplier =
|
||||
applicator.getTypeApplier(type.getNestedTypeDefinitionRecordNumber());
|
||||
return nestedTypeDefinitionApplier.getDataType();
|
||||
}
|
||||
|
||||
private DataType applyNestedTypeExtMsType(AbstractNestedTypeExtMsType type) {
|
||||
nestedTypeDefinitionApplier = applicator.getTypeApplier(type.getNestedTypeDefinitionRecordNumber());
|
||||
nestedTypeDefinitionApplier =
|
||||
applicator.getTypeApplier(type.getNestedTypeDefinitionRecordNumber());
|
||||
return nestedTypeDefinitionApplier.getDataType();
|
||||
}
|
||||
|
||||
|
@ -163,7 +165,7 @@ public class NestedTypeApplier extends AbstractMsTypeApplier {
|
|||
// return modifiedTypeApplier.getCycleBreakType(applicator);
|
||||
}
|
||||
|
||||
public AbstractMsTypeApplier getNestedTypeApplier() {
|
||||
MsTypeApplier getNestedTypeApplier() {
|
||||
return nestedTypeDefinitionApplier;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,26 +19,31 @@ import ghidra.app.util.bin.format.pdb2.pdbreader.symbol.AbstractMsSymbol;
|
|||
import ghidra.app.util.pdb.pdbapplicator.SymbolGroup.AbstractMsSymbolIterator;
|
||||
|
||||
/**
|
||||
* A dummy {@link AbstractMsSymbolApplier}, which, at a minimum, reads the symbol from the
|
||||
* {@link SymbolGroup}, allowing proper sequencing of other symbols within the
|
||||
* {@link SymbolGroup}.
|
||||
* A dummy {@link MsSymbolApplier}, which, at a minimum, reads the symbol from the
|
||||
* {@link SymbolGroup}, allowing proper sequencing of other symbols within the
|
||||
* {@link SymbolGroup}.
|
||||
*/
|
||||
public class NoSymbolApplier extends AbstractMsSymbolApplier {
|
||||
public class NoSymbolApplier extends MsSymbolApplier {
|
||||
|
||||
AbstractMsSymbol symbol;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param applicator the {@link PdbApplicator} for which we are working.
|
||||
* @param iter the Iterator containing the symbol sequence being processed
|
||||
*/
|
||||
public NoSymbolApplier(PdbApplicator applicator, AbstractMsSymbolIterator iter) {
|
||||
super(applicator, iter);
|
||||
symbol = iter.next();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyTo(AbstractMsSymbolApplier applyToApplier) {
|
||||
void applyTo(MsSymbolApplier applyToApplier) {
|
||||
// Do nothing.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply() {
|
||||
void apply() {
|
||||
// Do nothing.
|
||||
}
|
||||
|
||||
|
|
|
@ -21,9 +21,9 @@ import ghidra.app.util.bin.format.pdb2.pdbreader.type.AbstractMsType;
|
|||
|
||||
/**
|
||||
* Used for creating a wrapper for when there is not associated type to the PDB type (or if we
|
||||
* have not yet created the association).
|
||||
* have not yet created the association).
|
||||
*/
|
||||
public class NoTypeApplier extends AbstractMsTypeApplier {
|
||||
public class NoTypeApplier extends MsTypeApplier {
|
||||
|
||||
/**
|
||||
* Constructor for nested type applier.
|
||||
|
@ -37,12 +37,12 @@ public class NoTypeApplier extends AbstractMsTypeApplier {
|
|||
}
|
||||
|
||||
@Override
|
||||
public BigInteger getSize() {
|
||||
BigInteger getSize() {
|
||||
return BigInteger.ZERO;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply() {
|
||||
void apply() {
|
||||
// Do nothing (maybe should log something... not sure)
|
||||
// applicator.getLog().appendMsg("");
|
||||
}
|
||||
|
|
|
@ -15,8 +15,9 @@
|
|||
*/
|
||||
package ghidra.app.util.pdb.pdbapplicator;
|
||||
|
||||
//----------------------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* Mode for {@link CppCompositeType} class layout.
|
||||
*/
|
||||
enum OoComponentLayoutMode {
|
||||
UNKNOWN, MEMBERS_ONLY, BASIC, SIMPLE, COMPLEX
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@ import ghidra.util.exception.CancelledException;
|
|||
|
||||
/**
|
||||
* Manages Address/Section/Segment-related PDB items.
|
||||
* Has method for providing real addresses.
|
||||
* Has method for providing real addresses.
|
||||
*/
|
||||
public class PdbAddressManager {
|
||||
|
||||
|
@ -72,19 +72,19 @@ public class PdbAddressManager {
|
|||
* @return The Address
|
||||
*/
|
||||
// Returns an address using the section and offset.
|
||||
Address reladdr(AddressMsSymbol symbol) {
|
||||
return reladdr(symbol.getSegment(), symbol.getOffset());
|
||||
Address getAddress(AddressMsSymbol symbol) {
|
||||
return getAddress(symbol.getSegment(), symbol.getOffset());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Address for the given section and offset. Will attempt to map the address
|
||||
* to a new address if the {@link PdbApplicatorOptions}
|
||||
* to a new address if the {@link PdbApplicatorOptions}
|
||||
* @param segment The segment
|
||||
* @param offset The offset
|
||||
* @return The Address, which can be {@code Address.NO_ADDRESS} if it was the original address.
|
||||
*/
|
||||
// Returns an address using the section and offset.
|
||||
Address reladdr(int segment, long offset) {
|
||||
Address getAddress(int segment, long offset) {
|
||||
if (segment < 0 || segment > allSegmentsInfo.size()) {
|
||||
return Address.NO_ADDRESS;
|
||||
}
|
||||
|
@ -102,9 +102,9 @@ public class PdbAddressManager {
|
|||
|
||||
/**
|
||||
* Write the mapped address for a query address, where where the mapping is
|
||||
* derived by using a the address of a PDB symbol as the key and finding the address of
|
||||
* a symbol in the program of the same "unique" name. This is accomplished using public
|
||||
* mangled symbols. If the program symbol came from the PDB, then it maps to itself.
|
||||
* derived by using a the address of a PDB symbol as the key and finding the address of
|
||||
* a symbol in the program of the same "unique" name. This is accomplished using public
|
||||
* mangled symbols. If the program symbol came from the PDB, then it maps to itself.
|
||||
* @param address the query address
|
||||
* @param remapAddress the mapped address
|
||||
*/
|
||||
|
@ -122,9 +122,9 @@ public class PdbAddressManager {
|
|||
|
||||
/**
|
||||
* Returns the Address of an existing symbol for the query address, where the mapping is
|
||||
* derived by using a the address of a PDB symbol as the key and finding the address of
|
||||
* a symbol in the program of the same "unique" name. This is accomplished using public
|
||||
* mangled symbols. If the program symbol came from the PDB, then it maps to itself.
|
||||
* derived by using a the address of a PDB symbol as the key and finding the address of
|
||||
* a symbol in the program of the same "unique" name. This is accomplished using public
|
||||
* mangled symbols. If the program symbol came from the PDB, then it maps to itself.
|
||||
* @param address the query address
|
||||
* @return the remapAddress
|
||||
*/
|
||||
|
@ -270,7 +270,7 @@ public class PdbAddressManager {
|
|||
long offset = sym.getOffset();
|
||||
int length = sym.getLength();
|
||||
int characteristics = sym.getCharacteristics();
|
||||
Address address = reladdr(sym);
|
||||
Address address = getAddress(sym);
|
||||
PdbLog.message(String.format("%s: [%04X:%08X](%s) Len:%08X, Characteristics:%08X", name,
|
||||
segment, offset, address.toString(), length, characteristics));
|
||||
}
|
||||
|
@ -307,7 +307,7 @@ public class PdbAddressManager {
|
|||
MemoryBlock[] blocks = mem.getBlocks();
|
||||
List<SegmentMapDescription> segmentMapList = pdb.getDatabaseInterface().getSegmentMapList();
|
||||
/**
|
||||
* Program has additional "Headers" block set up by the {@link PeLoader}.
|
||||
* Program has additional "Headers" block set up by the {@link PeLoader}.
|
||||
*/
|
||||
int progIndexLimit = blocks.length;
|
||||
int pdbIndexLimit = segmentMapList.size();
|
||||
|
|
|
@ -25,7 +25,7 @@ import ghidra.app.util.bin.format.pdb2.pdbreader.*;
|
|||
import ghidra.app.util.bin.format.pdb2.pdbreader.symbol.*;
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.type.AbstractMsType;
|
||||
import ghidra.app.util.importer.MessageLog;
|
||||
import ghidra.app.util.pdb.PdbCategoryUtils;
|
||||
import ghidra.app.util.pdb.PdbCategories;
|
||||
import ghidra.app.util.pdb.pdbapplicator.SymbolGroup.AbstractMsSymbolIterator;
|
||||
import ghidra.graph.*;
|
||||
import ghidra.graph.algo.GraphNavigator;
|
||||
|
@ -36,11 +36,29 @@ import ghidra.program.model.lang.Register;
|
|||
import ghidra.program.model.listing.*;
|
||||
import ghidra.program.model.symbol.*;
|
||||
import ghidra.util.Msg;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.exception.InvalidInputException;
|
||||
import ghidra.util.exception.*;
|
||||
import ghidra.util.task.CancelOnlyWrappingTaskMonitor;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
/**
|
||||
* The main engine for applying an AbstractPdb to Ghidra, whether a Program or DataTypeManager.
|
||||
* The class is to be constructed first.
|
||||
* <p>
|
||||
* The
|
||||
* {@link #applyTo(Program, DataTypeManager, Address, PdbApplicatorOptions, TaskMonitor, MessageLog)}
|
||||
* method is then called with the appropriate {@link PdbApplicatorOptions} along with a
|
||||
* {@link Program} and/or {@link DataTypeManager}. Either, but not both can be null.
|
||||
* If the Program is not null but the DatatypeManager is null, then the DataTypeManager is gotten
|
||||
* from the Program. If the Program is null, then data types can be applied to a DataTypeManager.
|
||||
* The validation logic for the parameters is found in
|
||||
* {@link #validateAndSetParameters(Program, DataTypeManager, Address, PdbApplicatorOptions, TaskMonitor, MessageLog)}.
|
||||
* <p>
|
||||
* Once the parameters are validated, appropriate classes and storage containers are constructed.
|
||||
* Then processing commences, first with data types, followed by symbol-related processing.
|
||||
* <p>
|
||||
* {@link PdbApplicatorMetrics} are captured during the processing and status and logging is
|
||||
* reported to various mechanisms including {@link Msg}, {@link MessageLog}, and {@link PdbLog}.
|
||||
*/
|
||||
public class PdbApplicator {
|
||||
|
||||
/**
|
||||
|
@ -49,7 +67,7 @@ public class PdbApplicator {
|
|||
* @param big BigInteger value to convert.
|
||||
* @return the integer value.
|
||||
*/
|
||||
public static long bigIntegerToLong(PdbApplicator myApplicator, BigInteger big) {
|
||||
static long bigIntegerToLong(PdbApplicator myApplicator, BigInteger big) {
|
||||
try {
|
||||
return big.longValueExact();
|
||||
}
|
||||
|
@ -67,7 +85,7 @@ public class PdbApplicator {
|
|||
* @param big BigInteger value to convert.
|
||||
* @return the integer value.
|
||||
*/
|
||||
public static int bigIntegerToInt(PdbApplicator myApplicator, BigInteger big) {
|
||||
static int bigIntegerToInt(PdbApplicator myApplicator, BigInteger big) {
|
||||
try {
|
||||
return big.intValueExact();
|
||||
}
|
||||
|
@ -106,11 +124,11 @@ public class PdbApplicator {
|
|||
|
||||
//==============================================================================================
|
||||
private int resolveCount;
|
||||
private PdbCategoryUtils categoryUtils;
|
||||
private PdbCategories categoryUtils;
|
||||
private PdbPrimitiveTypeApplicator pdbPrimitiveTypeApplicator;
|
||||
private TypeApplierParser typeApplierParser;
|
||||
private TypeApplierFactory typeApplierParser;
|
||||
private ComplexTypeApplierMapper complexApplierMapper;
|
||||
private JungDirectedGraph<AbstractMsTypeApplier, GEdge<AbstractMsTypeApplier>> applierDependencyGraph;
|
||||
private JungDirectedGraph<MsTypeApplier, GEdge<MsTypeApplier>> applierDependencyGraph;
|
||||
/**
|
||||
* This namespace map documents as follows:
|
||||
* <PRE>
|
||||
|
@ -121,7 +139,7 @@ public class PdbApplicator {
|
|||
private Map<SymbolPath, Boolean> isClassByNamespace;
|
||||
|
||||
//==============================================================================================
|
||||
private SymbolApplierParser symbolApplierParser;
|
||||
private SymbolApplierFactory symbolApplierParser;
|
||||
|
||||
// Investigating... might change from String to AbstractSymbolApplier.
|
||||
private Map<Address, Set<String>> labelsByAddress;
|
||||
|
@ -142,13 +160,13 @@ public class PdbApplicator {
|
|||
//==============================================================================================
|
||||
/**
|
||||
* Applies the PDB to the {@link Program} or {@link DataTypeManager}. Either, but not both,
|
||||
* can be null.
|
||||
* can be null.
|
||||
* @param programParam The {@link Program} to which to apply the PDB. Can be null in certain
|
||||
* circumstances.
|
||||
* circumstances.
|
||||
* @param dataTypeManagerParam The {@link DataTypeManager} to which to apply data types. Can be
|
||||
* null in certain circumstances.
|
||||
* null in certain circumstances.
|
||||
* @param imageBaseParam Address bases from which symbol addresses are based. If null, uses
|
||||
* the image base of the program (both cannot be null).
|
||||
* the image base of the program (both cannot be null).
|
||||
* @param applicatorOptionsParam {@link PdbApplicatorOptions} used for applying the PDB.
|
||||
* @param monitorParam TaskMonitor uses for watching progress and cancellation notices.
|
||||
* @param logParam The MessageLog to which to output messages.
|
||||
|
@ -187,7 +205,7 @@ public class PdbApplicator {
|
|||
private void processTypes() throws CancelledException, PdbException {
|
||||
setMonitorMessage("PDB: Applying to DTM " + dataTypeManager.getName() + "...");
|
||||
|
||||
PdbResearch.initCheckBreak(); // for developmental debug
|
||||
PdbResearch.initBreakPointRecordNumbers(); // for developmental debug
|
||||
|
||||
resolveCount = 0;
|
||||
|
||||
|
@ -279,7 +297,7 @@ public class PdbApplicator {
|
|||
|
||||
categoryUtils = setPdbCatogoryUtils(pdbFilename);
|
||||
pdbPrimitiveTypeApplicator = new PdbPrimitiveTypeApplicator(dataTypeManager);
|
||||
typeApplierParser = new TypeApplierParser(this);
|
||||
typeApplierParser = new TypeApplierFactory(this);
|
||||
complexApplierMapper = new ComplexTypeApplierMapper(this);
|
||||
applierDependencyGraph = new JungDirectedGraph<>();
|
||||
isClassByNamespace = new TreeMap<>();
|
||||
|
@ -294,7 +312,7 @@ public class PdbApplicator {
|
|||
vbtManager = new VbtManager(getDataTypeManager());
|
||||
}
|
||||
|
||||
symbolApplierParser = new SymbolApplierParser(this);
|
||||
symbolApplierParser = new SymbolApplierFactory(this);
|
||||
|
||||
// Investigations
|
||||
labelsByAddress = new HashMap<>();
|
||||
|
@ -378,6 +396,16 @@ public class PdbApplicator {
|
|||
log.appendMsg(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Puts message to {@link PdbLog} and to Msg.info()
|
||||
* @param originator a Logger instance, "this", or YourClass.class
|
||||
* @param message the message to display
|
||||
*/
|
||||
void pdbLogAndInfoMessage(Object originator, String message) {
|
||||
PdbLog.message(message);
|
||||
Msg.info(originator, message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link TaskMonitor} to available for this analyzer.
|
||||
* @return the monitor.
|
||||
|
@ -387,7 +415,9 @@ public class PdbApplicator {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link CancelOnlyWrappingTaskMonitor} to available for this analyzer.
|
||||
* Returns the {@link CancelOnlyWrappingTaskMonitor} to available for this analyzer. This is
|
||||
* useful for the user to be able to control the monitor progress bar without called commands
|
||||
* changing its progress on smaller tasks.
|
||||
* @return the monitor.
|
||||
*/
|
||||
TaskMonitor getCancelOnlyWrappingMonitor() {
|
||||
|
@ -443,9 +473,9 @@ public class PdbApplicator {
|
|||
//==============================================================================================
|
||||
/**
|
||||
* Get the {@link CategoryPath} associated with the {@link SymbolPath} specified, rooting
|
||||
* it either at the PDB Category.
|
||||
* it either at the PDB Category.
|
||||
* @param symbolPath Symbol path to be used to create the CategoryPath. Null represents global
|
||||
* namespace.
|
||||
* namespace.
|
||||
* @return {@link CategoryPath} created for the input.
|
||||
*/
|
||||
CategoryPath getCategory(SymbolPath symbolPath) {
|
||||
|
@ -476,7 +506,7 @@ public class PdbApplicator {
|
|||
* Returns the {@link CategoryPath} for Anonymous Types Category for the PDB.
|
||||
* @return the {@link CategoryPath}
|
||||
*/
|
||||
public CategoryPath getAnonymousTypesCategory() {
|
||||
CategoryPath getAnonymousTypesCategory() {
|
||||
return categoryUtils.getAnonymousTypesCategory();
|
||||
}
|
||||
|
||||
|
@ -498,7 +528,7 @@ public class PdbApplicator {
|
|||
categoryUtils.incrementNextAnonymousFunctionName();
|
||||
}
|
||||
|
||||
private PdbCategoryUtils setPdbCatogoryUtils(String pdbFilename)
|
||||
private PdbCategories setPdbCatogoryUtils(String pdbFilename)
|
||||
throws CancelledException, PdbException {
|
||||
|
||||
List<String> categoryNames = new ArrayList<>();
|
||||
|
@ -514,18 +544,18 @@ public class PdbApplicator {
|
|||
if (index == -1) {
|
||||
index = pdbFilename.lastIndexOf("/");
|
||||
}
|
||||
return new PdbCategoryUtils(pdbFilename.substring(index + 1), categoryNames);
|
||||
return new PdbCategories(pdbFilename.substring(index + 1), categoryNames);
|
||||
}
|
||||
|
||||
//==============================================================================================
|
||||
// Applier-based-DataType-dependency-related methods.
|
||||
//==============================================================================================
|
||||
void addApplierDependency(AbstractMsTypeApplier depender) {
|
||||
void addApplierDependency(MsTypeApplier depender) {
|
||||
Objects.requireNonNull(depender);
|
||||
applierDependencyGraph.addVertex(depender.getDependencyApplier());
|
||||
}
|
||||
|
||||
void addApplierDependency(AbstractMsTypeApplier depender, AbstractMsTypeApplier dependee) {
|
||||
void addApplierDependency(MsTypeApplier depender, MsTypeApplier dependee) {
|
||||
Objects.requireNonNull(depender);
|
||||
Objects.requireNonNull(dependee);
|
||||
// TODO: Possibly do checks on dependee and depender types for actual creation
|
||||
|
@ -541,7 +571,7 @@ public class PdbApplicator {
|
|||
new DefaultGEdge<>(depender.getDependencyApplier(), dependee.getDependencyApplier()));
|
||||
}
|
||||
|
||||
List<AbstractMsTypeApplier> getVerticesInPostOrder() {
|
||||
List<MsTypeApplier> getVerticesInPostOrder() {
|
||||
setMonitorMessage("PDB: Determining data type dependency order...");
|
||||
return GraphAlgorithms.getVerticesInPostOrder(applierDependencyGraph,
|
||||
GraphNavigator.topDownNavigator());
|
||||
|
@ -550,29 +580,28 @@ public class PdbApplicator {
|
|||
//==============================================================================================
|
||||
//==============================================================================================
|
||||
//==============================================================================================
|
||||
AbstractMsTypeApplier getApplierSpec(RecordNumber recordNumber,
|
||||
Class<? extends AbstractMsTypeApplier> expected) throws PdbException {
|
||||
MsTypeApplier getApplierSpec(RecordNumber recordNumber, Class<? extends MsTypeApplier> expected)
|
||||
throws PdbException {
|
||||
return typeApplierParser.getApplierSpec(recordNumber, expected);
|
||||
}
|
||||
|
||||
AbstractMsTypeApplier getApplierOrNoTypeSpec(RecordNumber recordNumber,
|
||||
Class<? extends AbstractMsTypeApplier> expected) throws PdbException {
|
||||
MsTypeApplier getApplierOrNoTypeSpec(RecordNumber recordNumber,
|
||||
Class<? extends MsTypeApplier> expected) throws PdbException {
|
||||
return typeApplierParser.getApplierOrNoTypeSpec(recordNumber, expected);
|
||||
}
|
||||
|
||||
AbstractMsTypeApplier getTypeApplier(RecordNumber recordNumber) {
|
||||
MsTypeApplier getTypeApplier(RecordNumber recordNumber) {
|
||||
return typeApplierParser.getTypeApplier(recordNumber);
|
||||
}
|
||||
|
||||
AbstractMsTypeApplier getTypeApplier(AbstractMsType type) {
|
||||
MsTypeApplier getTypeApplier(AbstractMsType type) {
|
||||
return typeApplierParser.getTypeApplier(type);
|
||||
}
|
||||
|
||||
//==============================================================================================
|
||||
//==============================================================================================
|
||||
//==============================================================================================
|
||||
public int findModuleNumberBySectionOffsetContribution(int section, long offset)
|
||||
throws PdbException {
|
||||
int findModuleNumberBySectionOffsetContribution(int section, long offset) throws PdbException {
|
||||
for (AbstractSectionContribution sectionContribution : pdb.getDatabaseInterface().getSectionContributionList()) {
|
||||
int sectionContributionOffset = sectionContribution.getOffset();
|
||||
int maxSectionContributionOffset =
|
||||
|
@ -594,8 +623,7 @@ public class PdbApplicator {
|
|||
tpi.getTypeIndexMin(); indexNumber < tpi.getTypeIndexMaxExclusive(); indexNumber++) {
|
||||
monitor.checkCanceled();
|
||||
PdbResearch.checkBreak(indexNumber);
|
||||
AbstractMsTypeApplier applier =
|
||||
getTypeApplier(RecordNumber.typeRecordNumber(indexNumber));
|
||||
MsTypeApplier applier = getTypeApplier(RecordNumber.typeRecordNumber(indexNumber));
|
||||
//PdbResearch.checkBreak(indexNumber, applier);
|
||||
applier.apply();
|
||||
monitor.incrementProgress(1);
|
||||
|
@ -657,8 +685,7 @@ public class PdbApplicator {
|
|||
setMonitorMessage("PDB: Processing " + num + " item type components...");
|
||||
for (int indexNumber = ipi.getTypeIndexMin(); indexNumber < num; indexNumber++) {
|
||||
monitor.checkCanceled();
|
||||
AbstractMsTypeApplier applier =
|
||||
getTypeApplier(RecordNumber.itemRecordNumber(indexNumber));
|
||||
MsTypeApplier applier = getTypeApplier(RecordNumber.itemRecordNumber(indexNumber));
|
||||
applier.apply();
|
||||
monitor.incrementProgress(1);
|
||||
}
|
||||
|
@ -672,11 +699,11 @@ public class PdbApplicator {
|
|||
|
||||
//==============================================================================================
|
||||
private void processDeferred() throws CancelledException, PdbException {
|
||||
List<AbstractMsTypeApplier> verticesInPostOrder = getVerticesInPostOrder();
|
||||
List<MsTypeApplier> verticesInPostOrder = getVerticesInPostOrder();
|
||||
monitor.initialize(verticesInPostOrder.size());
|
||||
setMonitorMessage("PDB: Processing " + verticesInPostOrder.size() +
|
||||
" deferred data type dependencies...");
|
||||
for (AbstractMsTypeApplier applier : verticesInPostOrder) {
|
||||
for (MsTypeApplier applier : verticesInPostOrder) {
|
||||
monitor.checkCanceled();
|
||||
PdbResearch.checkBreak(applier.index);
|
||||
//checkBreak(applier.index, applier);
|
||||
|
@ -699,8 +726,7 @@ public class PdbApplicator {
|
|||
tpi.getTypeIndexMin(); indexNumber < tpi.getTypeIndexMaxExclusive(); indexNumber++) {
|
||||
monitor.checkCanceled();
|
||||
PdbResearch.checkBreak(indexNumber);
|
||||
AbstractMsTypeApplier applier =
|
||||
getTypeApplier(RecordNumber.typeRecordNumber(indexNumber));
|
||||
MsTypeApplier applier = getTypeApplier(RecordNumber.typeRecordNumber(indexNumber));
|
||||
PdbResearch.checkBreak(indexNumber, applier);
|
||||
applier.resolve();
|
||||
monitor.incrementProgress(1);
|
||||
|
@ -758,8 +784,8 @@ public class PdbApplicator {
|
|||
* @param symbol The {@link AddressMsSymbol}
|
||||
* @return The Address
|
||||
*/
|
||||
Address reladdr(AddressMsSymbol symbol) {
|
||||
return pdbAddressManager.reladdr(symbol);
|
||||
Address getAddress(AddressMsSymbol symbol) {
|
||||
return pdbAddressManager.getAddress(symbol);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -768,15 +794,15 @@ public class PdbApplicator {
|
|||
* @param offset The offset
|
||||
* @return The Address
|
||||
*/
|
||||
Address reladdr(int segment, long offset) {
|
||||
return pdbAddressManager.reladdr(segment, offset);
|
||||
Address getAddress(int segment, long offset) {
|
||||
return pdbAddressManager.getAddress(segment, offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the mapped address for a query address, where where the mapping is
|
||||
* derived by using a the address of a PDB symbol as the key and finding the address of
|
||||
* a symbol in the program of the same "unique" name. This is accomplished using public
|
||||
* mangled symbols. If the program symbol came from the PDB, then it maps to itself.
|
||||
* derived by using a the address of a PDB symbol as the key and finding the address of
|
||||
* a symbol in the program of the same "unique" name. This is accomplished using public
|
||||
* mangled symbols. If the program symbol came from the PDB, then it maps to itself.
|
||||
* @param address the query address
|
||||
* @param remapAddress the mapped address
|
||||
*/
|
||||
|
@ -786,9 +812,9 @@ public class PdbApplicator {
|
|||
|
||||
/**
|
||||
* Returns the Address of an existing symbol for the query address, where the mapping is
|
||||
* derived by using a the address of a PDB symbol as the key and finding the address of
|
||||
* a symbol in the program of the same "unique" name. This is accomplished using public
|
||||
* mangled symbols. If the program symbol came from the PDB, then it maps to itself.
|
||||
* derived by using a the address of a PDB symbol as the key and finding the address of
|
||||
* a symbol in the program of the same "unique" name. This is accomplished using public
|
||||
* mangled symbols. If the program symbol came from the PDB, then it maps to itself.
|
||||
* @param address the query address
|
||||
* @return the remapAddress
|
||||
*/
|
||||
|
@ -1131,15 +1157,14 @@ public class PdbApplicator {
|
|||
//==============================================================================================
|
||||
//==============================================================================================
|
||||
//==============================================================================================
|
||||
AbstractMsSymbolApplier getSymbolApplier(AbstractMsSymbolIterator iter)
|
||||
throws CancelledException, NoSuchElementException {
|
||||
MsSymbolApplier getSymbolApplier(AbstractMsSymbolIterator iter) throws CancelledException {
|
||||
return symbolApplierParser.getSymbolApplier(iter);
|
||||
}
|
||||
|
||||
//==============================================================================================
|
||||
void procSym(AbstractMsSymbolIterator iter) throws CancelledException {
|
||||
try {
|
||||
AbstractMsSymbolApplier applier = getSymbolApplier(iter);
|
||||
MsSymbolApplier applier = getSymbolApplier(iter);
|
||||
applier.apply();
|
||||
}
|
||||
catch (PdbException e) {
|
||||
|
@ -1216,7 +1241,7 @@ public class PdbApplicator {
|
|||
symbolTable.createNameSpace(parentNamespace, name, SourceType.IMPORTED);
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
catch (InvalidInputException | DuplicateNameException e) {
|
||||
log.appendMsg("Unable to create class namespace: " + parentNamespace.getName(true) +
|
||||
Namespace.DELIMITER + name + " due to exception: " + e.toString());
|
||||
}
|
||||
|
|
|
@ -25,68 +25,70 @@ import ghidra.program.model.listing.Program;
|
|||
|
||||
/**
|
||||
* Metrics captured during the application of a PDB. This is a Ghidra class separate from the
|
||||
* PDB API that we have crafted to help us quantify and qualify the ability apply the PDB
|
||||
* to a {@link DataTypeManager} and/or {@link Program}.
|
||||
* PDB API that we have crafted to help us quantify and qualify the ability apply the PDB
|
||||
* to a {@link DataTypeManager} and/or {@link Program}.
|
||||
*/
|
||||
public class PdbApplicatorMetrics {
|
||||
|
||||
/**
|
||||
* List of symbols seen (by their ID) as Global symbols.
|
||||
*/
|
||||
private static Set<Integer> expectedGlobalSymbols = new HashSet<>();
|
||||
static {
|
||||
//@formatter:off
|
||||
private static final Set<Integer> expectedGlobalSymbols = Set.of(
|
||||
// AbstractReferenceMsSymbol
|
||||
expectedGlobalSymbols.add(DataReferenceStMsSymbol.PDB_ID);
|
||||
expectedGlobalSymbols.add(DataReferenceMsSymbol.PDB_ID);
|
||||
expectedGlobalSymbols.add(LocalProcedureReferenceMsSymbol.PDB_ID);
|
||||
expectedGlobalSymbols.add(LocalProcedureReferenceStMsSymbol.PDB_ID);
|
||||
expectedGlobalSymbols.add(ProcedureReferenceMsSymbol.PDB_ID);
|
||||
expectedGlobalSymbols.add(ProcedureReferenceStMsSymbol.PDB_ID);
|
||||
expectedGlobalSymbols.add(AnnotationReferenceMsSymbol.PDB_ID);
|
||||
expectedGlobalSymbols.add(TokenReferenceToManagedProcedureMsSymbol.PDB_ID);
|
||||
DataReferenceStMsSymbol.PDB_ID,
|
||||
DataReferenceMsSymbol.PDB_ID,
|
||||
LocalProcedureReferenceMsSymbol.PDB_ID,
|
||||
LocalProcedureReferenceStMsSymbol.PDB_ID,
|
||||
ProcedureReferenceMsSymbol.PDB_ID,
|
||||
ProcedureReferenceStMsSymbol.PDB_ID,
|
||||
AnnotationReferenceMsSymbol.PDB_ID,
|
||||
TokenReferenceToManagedProcedureMsSymbol.PDB_ID,
|
||||
|
||||
// AbstractDataMsSymbol
|
||||
expectedGlobalSymbols.add(GlobalData16MsSymbol.PDB_ID);
|
||||
expectedGlobalSymbols.add(GlobalData3216MsSymbol.PDB_ID);
|
||||
expectedGlobalSymbols.add(GlobalData32MsSymbol.PDB_ID);
|
||||
expectedGlobalSymbols.add(GlobalData32StMsSymbol.PDB_ID);
|
||||
expectedGlobalSymbols.add(LocalData16MsSymbol.PDB_ID);
|
||||
expectedGlobalSymbols.add(LocalData3216MsSymbol.PDB_ID);
|
||||
expectedGlobalSymbols.add(LocalData32MsSymbol.PDB_ID);
|
||||
expectedGlobalSymbols.add(LocalData32StMsSymbol.PDB_ID);
|
||||
expectedGlobalSymbols.add(GlobalManagedDataMsSymbol.PDB_ID);
|
||||
expectedGlobalSymbols.add(GlobalManagedDataStMsSymbol.PDB_ID);
|
||||
expectedGlobalSymbols.add(LocalManagedDataMsSymbol.PDB_ID);
|
||||
expectedGlobalSymbols.add(LocalManagedDataStMsSymbol.PDB_ID);
|
||||
GlobalData16MsSymbol.PDB_ID,
|
||||
GlobalData3216MsSymbol.PDB_ID,
|
||||
GlobalData32MsSymbol.PDB_ID,
|
||||
GlobalData32StMsSymbol.PDB_ID,
|
||||
LocalData16MsSymbol.PDB_ID,
|
||||
LocalData3216MsSymbol.PDB_ID,
|
||||
LocalData32MsSymbol.PDB_ID,
|
||||
LocalData32StMsSymbol.PDB_ID,
|
||||
GlobalManagedDataMsSymbol.PDB_ID,
|
||||
GlobalManagedDataStMsSymbol.PDB_ID,
|
||||
LocalManagedDataMsSymbol.PDB_ID,
|
||||
LocalManagedDataStMsSymbol.PDB_ID,
|
||||
|
||||
// AbstractUserDefinedTypeMsSymbol
|
||||
expectedGlobalSymbols.add(CobolUserDefinedType16MsSymbol.PDB_ID);
|
||||
expectedGlobalSymbols.add(CobolUserDefinedTypeMsSymbol.PDB_ID);
|
||||
expectedGlobalSymbols.add(CobolUserDefinedTypeStMsSymbol.PDB_ID);
|
||||
expectedGlobalSymbols.add(UserDefinedType16MsSymbol.PDB_ID);
|
||||
expectedGlobalSymbols.add(UserDefinedTypeMsSymbol.PDB_ID);
|
||||
expectedGlobalSymbols.add(UserDefinedTypeStMsSymbol.PDB_ID);
|
||||
CobolUserDefinedType16MsSymbol.PDB_ID,
|
||||
CobolUserDefinedTypeMsSymbol.PDB_ID,
|
||||
CobolUserDefinedTypeStMsSymbol.PDB_ID,
|
||||
UserDefinedType16MsSymbol.PDB_ID,
|
||||
UserDefinedTypeMsSymbol.PDB_ID,
|
||||
UserDefinedTypeStMsSymbol.PDB_ID,
|
||||
|
||||
// AbstractConstantMsSymbol
|
||||
expectedGlobalSymbols.add(Constant16MsSymbol.PDB_ID);
|
||||
expectedGlobalSymbols.add(ConstantMsSymbol.PDB_ID);
|
||||
expectedGlobalSymbols.add(ConstantStMsSymbol.PDB_ID);
|
||||
expectedGlobalSymbols.add(ManagedConstantMsSymbol.PDB_ID);
|
||||
}
|
||||
Constant16MsSymbol.PDB_ID,
|
||||
ConstantMsSymbol.PDB_ID,
|
||||
ConstantStMsSymbol.PDB_ID,
|
||||
ManagedConstantMsSymbol.PDB_ID
|
||||
);
|
||||
//@formatter:on
|
||||
|
||||
/**
|
||||
* List of symbols seen (by their ID) as Public symbols.
|
||||
*/
|
||||
private static Set<Integer> expectedLinkerSymbols = new HashSet<>();
|
||||
static {
|
||||
expectedLinkerSymbols.add(PeCoffSectionMsSymbol.PDB_ID);
|
||||
expectedLinkerSymbols.add(TrampolineMsSymbol.PDB_ID);
|
||||
expectedLinkerSymbols.add(ObjectNameMsSymbol.PDB_ID);
|
||||
expectedLinkerSymbols.add(Compile3MsSymbol.PDB_ID);
|
||||
expectedLinkerSymbols.add(Compile2MsSymbol.PDB_ID);
|
||||
expectedLinkerSymbols.add(Compile2StMsSymbol.PDB_ID);
|
||||
expectedLinkerSymbols.add(EnvironmentBlockMsSymbol.PDB_ID);
|
||||
}
|
||||
//@formatter:off
|
||||
private static final Set<Integer> expectedLinkerSymbols = Set.of(
|
||||
PeCoffSectionMsSymbol.PDB_ID,
|
||||
TrampolineMsSymbol.PDB_ID,
|
||||
ObjectNameMsSymbol.PDB_ID,
|
||||
Compile3MsSymbol.PDB_ID,
|
||||
Compile2MsSymbol.PDB_ID,
|
||||
Compile2StMsSymbol.PDB_ID,
|
||||
EnvironmentBlockMsSymbol.PDB_ID
|
||||
);
|
||||
//@formatter:on
|
||||
|
||||
private Set<Class<? extends AbstractMsType>> cannotApplyTypes = new HashSet<>();
|
||||
private Set<Class<? extends AbstractMsType>> unexpectedMemberFunctionThisPointerTypes =
|
||||
|
@ -104,7 +106,7 @@ public class PdbApplicatorMetrics {
|
|||
* Method to capture data/item type that cannot be applied.
|
||||
* @param type The data/item type witnessed.
|
||||
*/
|
||||
public void witnessCannotApplyDataType(AbstractMsType type) {
|
||||
void witnessCannotApplyDataType(AbstractMsType type) {
|
||||
cannotApplyTypes.add(type.getClass());
|
||||
}
|
||||
|
||||
|
@ -112,7 +114,7 @@ public class PdbApplicatorMetrics {
|
|||
* Method to capture symbol type that cannot be applied.
|
||||
* @param symbol The symbol type witnessed.
|
||||
*/
|
||||
public void witnessCannotApplySymbolType(AbstractMsSymbol symbol) {
|
||||
void witnessCannotApplySymbolType(AbstractMsSymbol symbol) {
|
||||
cannotApplySymbols.add(symbol.getClass());
|
||||
}
|
||||
|
||||
|
@ -120,7 +122,7 @@ public class PdbApplicatorMetrics {
|
|||
* Method to capture symbol type that was unexpected as a Global symbol.
|
||||
* @param symbol The symbol type witnessed.
|
||||
*/
|
||||
public void witnessGlobalSymbolType(AbstractMsSymbol symbol) {
|
||||
void witnessGlobalSymbolType(AbstractMsSymbol symbol) {
|
||||
if (!expectedGlobalSymbols.contains(symbol.getPdbId())) {
|
||||
unexpectedGlobalSymbols.add(symbol.getClass());
|
||||
}
|
||||
|
@ -130,7 +132,7 @@ public class PdbApplicatorMetrics {
|
|||
* Method to capture symbol type that was unexpected as a Public symbol.
|
||||
* @param symbol The symbol type witnessed.
|
||||
*/
|
||||
public void witnessPublicSymbolType(AbstractMsSymbol symbol) {
|
||||
void witnessPublicSymbolType(AbstractMsSymbol symbol) {
|
||||
if (!(symbol instanceof AbstractPublicMsSymbol)) {
|
||||
unexpectedPublicSymbols.add(symbol.getClass());
|
||||
}
|
||||
|
@ -140,7 +142,7 @@ public class PdbApplicatorMetrics {
|
|||
* Method to capture symbol type that was unexpected as a Linker symbol.
|
||||
* @param symbol The symbol type witnessed.
|
||||
*/
|
||||
public void witnessLinkerSymbolType(AbstractMsSymbol symbol) {
|
||||
void witnessLinkerSymbolType(AbstractMsSymbol symbol) {
|
||||
if (!expectedLinkerSymbols.contains(symbol.getPdbId())) {
|
||||
// do nothing for now
|
||||
}
|
||||
|
@ -149,7 +151,7 @@ public class PdbApplicatorMetrics {
|
|||
/**
|
||||
* Method to capture witnessing of Enumerate narrowing.
|
||||
*/
|
||||
public void witnessEnumerateNarrowing() {
|
||||
void witnessEnumerateNarrowing() {
|
||||
witnessEnumerateNarrowing = true;
|
||||
}
|
||||
|
||||
|
@ -157,7 +159,7 @@ public class PdbApplicatorMetrics {
|
|||
* Method to capture unusual this pointer types.
|
||||
* @param applier The {@AbstractMsTypeApplier} for the supposed this pointer.
|
||||
*/
|
||||
public void witnessMemberFunctionThisPointer(AbstractMsTypeApplier applier) {
|
||||
void witnessMemberFunctionThisPointer(MsTypeApplier applier) {
|
||||
// We know that we have seen PrimitiveMsTypes that are pointer types.
|
||||
if (applier instanceof PointerTypeApplier) {
|
||||
return;
|
||||
|
@ -169,7 +171,7 @@ public class PdbApplicatorMetrics {
|
|||
* Method to capture unusual underlying types for a normal pointer for this pointer.
|
||||
* @param applier The {@AbstractMsTypeApplier} for the supposed this pointer.
|
||||
*/
|
||||
public void witnessMemberFunctionThisPointerUnderlyingType(AbstractMsTypeApplier applier) {
|
||||
void witnessMemberFunctionThisPointerUnderlyingType(MsTypeApplier applier) {
|
||||
if (applier instanceof CompositeTypeApplier) {
|
||||
return;
|
||||
}
|
||||
|
@ -180,7 +182,7 @@ public class PdbApplicatorMetrics {
|
|||
* Method to capture unusual containing types for a member function.
|
||||
* @param applier The {@AbstractMsTypeApplier} for the supposed this pointer.
|
||||
*/
|
||||
public void witnessMemberFunctionContainingType(AbstractMsTypeApplier applier) {
|
||||
void witnessMemberFunctionContainingType(MsTypeApplier applier) {
|
||||
if (applier instanceof CompositeTypeApplier) {
|
||||
return;
|
||||
}
|
||||
|
@ -193,7 +195,7 @@ public class PdbApplicatorMetrics {
|
|||
* Return some post-processing metrics for applying the PDB
|
||||
* @return {@link String} of pretty output.
|
||||
*/
|
||||
public String getPostProcessingReport() {
|
||||
String getPostProcessingReport() {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append("===Begin PdbApplicatorMetrics Report===\n");
|
||||
builder.append(reportNonappliableTypes());
|
||||
|
|
|
@ -22,7 +22,7 @@ import ghidra.app.util.bin.format.pdb2.pdbreader.AbstractPdb;
|
|||
* Ghidra program. These can be optional values used during our development of this PdbApplicator,
|
||||
* and thus might not be found in the finished product.
|
||||
*/
|
||||
public class PdbApplicatorOptions extends Exception {
|
||||
public class PdbApplicatorOptions {
|
||||
|
||||
private static final boolean defaultApplyCodeScopeBlockComments = false;
|
||||
private static final boolean defaultApplyInstructionLabels = false;
|
||||
|
@ -110,7 +110,7 @@ public class PdbApplicatorOptions extends Exception {
|
|||
|
||||
/**
|
||||
* Enable/disable the option to only apply data types (skipping symbol information).
|
||||
* In other words, the default is to apply symbols.
|
||||
* In other words, the default is to apply symbols.
|
||||
* @param applyDataTypesOnly {@code true} to turn applyDataTypesOnly on
|
||||
*/
|
||||
public void setApplyDataTypesOnly(boolean applyDataTypesOnly) {
|
||||
|
@ -143,7 +143,7 @@ public class PdbApplicatorOptions extends Exception {
|
|||
|
||||
/**
|
||||
* Enable/disable the option to attempt to map addresses using existing mangled symbols
|
||||
* (typically public symbols).
|
||||
* (typically public symbols).
|
||||
* @param enable {@code true} to turn remapAddressesUsingExistingPublicSymbols on
|
||||
*/
|
||||
public void setRemapAddressUsingExistingPublicMangledSymbols(boolean enable) {
|
||||
|
@ -160,9 +160,9 @@ public class PdbApplicatorOptions extends Exception {
|
|||
|
||||
/**
|
||||
* Enable/disable the option to allow another symbol be set to primary when the existing
|
||||
* primary symbol is a mangled symbol, regardless of the Symbol SourceType. This is
|
||||
* typically used when we can get better data type information from the PDB record than
|
||||
* we can from the demangler.
|
||||
* primary symbol is a mangled symbol, regardless of the Symbol SourceType. This is
|
||||
* typically used when we can get better data type information from the PDB record than
|
||||
* we can from the demangler.
|
||||
* @param enable {@code true} to turn allowDemotePrimaryMangledSymbol on
|
||||
*/
|
||||
public void setAllowDemotePrimaryMangledSymbol(boolean enable) {
|
||||
|
@ -179,7 +179,7 @@ public class PdbApplicatorOptions extends Exception {
|
|||
|
||||
/**
|
||||
* Enable/disable the option to apply function params and locals, which might produce improper
|
||||
* results.
|
||||
* results.
|
||||
* @param applyFunctionVariables {@code true} to turn applyPublicSymbolsOnly on
|
||||
*/
|
||||
public void setApplyFunctionVariables(boolean applyFunctionVariables) {
|
||||
|
|
|
@ -24,7 +24,7 @@ import ghidra.util.exception.AssertException;
|
|||
|
||||
/**
|
||||
* Takes care of allocating unique instances of primitive data types for the {@link PdbApplicator},
|
||||
* and is used principally by the many instances of {@link PrimitiveTypeApplier}.
|
||||
* and is used principally by the many instances of {@link PrimitiveTypeApplier}.
|
||||
*/
|
||||
public class PdbPrimitiveTypeApplicator {
|
||||
|
||||
|
|
|
@ -28,12 +28,13 @@ import ghidra.util.Msg;
|
|||
public class PdbRegisterNameToProgramRegisterMapper {
|
||||
|
||||
// Only need to map names that are different (probably not counting case, as rsp and RSP
|
||||
// are equivalent.
|
||||
private static Map<String, String> registerNameMap = new HashMap<>();
|
||||
static {
|
||||
//registerNameMap.put("rsp", "RSP");
|
||||
registerNameMap.put("fbp", "RBP");
|
||||
}
|
||||
// are equivalent.
|
||||
//@formatter:off
|
||||
private static Map<String, String> registerNameMap = Map.of(
|
||||
//"rsp", "RSP",
|
||||
"fbp", "RBP"
|
||||
);
|
||||
//@formatter:on
|
||||
|
||||
private Program program;
|
||||
private Map<String, Register> pdbRegisterNameToRegisterMap;
|
||||
|
|
|
@ -31,13 +31,24 @@ import ghidra.util.task.TaskMonitor;
|
|||
import mdemangler.*;
|
||||
import mdemangler.object.MDObjectCPP;
|
||||
|
||||
/**
|
||||
* This is a class for develop research into various areas. Anything in this class that needs to
|
||||
* end up as part of any usable output should be moved into another class. This class just
|
||||
* aggregates various items being investigated, and will eventually be eliminated from the code
|
||||
* base.
|
||||
*/
|
||||
public class PdbResearch {
|
||||
|
||||
//==============================================================================================
|
||||
private static Set<Integer> debugIndexNumbers;
|
||||
|
||||
//==============================================================================================
|
||||
static void initCheckBreak() {
|
||||
/**
|
||||
* This method is used to populate debugIndexNumbers set that gets used by
|
||||
* {@link #checkBreak(int recordNumber)} in which we set a breakpoint on {@code int a = 1;} to
|
||||
* then allow us to debug into other code.
|
||||
*/
|
||||
static void initBreakPointRecordNumbers() {
|
||||
debugIndexNumbers = new TreeSet<>();
|
||||
|
||||
debugIndexNumbers.add(12527);
|
||||
|
@ -278,7 +289,14 @@ public class PdbResearch {
|
|||
|
||||
/**
|
||||
* Developmental method for breakpoints. TODO: will delete this from production.
|
||||
* @param recordNumber tmp (set negative to ignore)
|
||||
* Set breakpoint on {@code int a = 1;}
|
||||
* @param recordNumber the record number tha is being processed (set negative to ignore)
|
||||
* <p>
|
||||
* This code is useful for developer debugging because the PDB is records-based and we often
|
||||
* need to set breakpoints elsewhere, determine what RecordNumber we are interested in, and
|
||||
* then use this method to set a breakpoint to catch when the record number is being seen
|
||||
* earlier in the state of processing. The numbers in {@link #debugIndexNumbers} is set
|
||||
* by {@link #initBreakPointRecordNumbers()}.
|
||||
*/
|
||||
static void checkBreak(int recordNumber) {
|
||||
if (debugIndexNumbers.contains(recordNumber)) {
|
||||
|
@ -289,10 +307,11 @@ public class PdbResearch {
|
|||
|
||||
/**
|
||||
* Developmental method for breakpoints. TODO: will delete this from production.
|
||||
* @param recordNumber tmp (set negative to ignore)
|
||||
* @param applier tmp
|
||||
* @param recordNumber the record number tha is being processed (set negative to ignore)
|
||||
* @param applier the applier that might have additional, such as the name of the type of
|
||||
* interest
|
||||
*/
|
||||
static void checkBreak(int recordNumber, AbstractMsTypeApplier applier) {
|
||||
static void checkBreak(int recordNumber, MsTypeApplier applier) {
|
||||
|
||||
String nn = applier.getMsType().getName();
|
||||
if ("std::__1::__map_value_compare<std::__1::basic_string<char>,std::__1::__value_type<std::__1::basic_string<char>,std::__1::basic_string<wchar_t> >,std::__1::less<void>,1>".equals(
|
||||
|
@ -341,7 +360,7 @@ public class PdbResearch {
|
|||
initDeveloperOrderRecordNumbers();
|
||||
for (int indexNumber : developerDebugOrderIndexNumbers) {
|
||||
monitor.checkCanceled();
|
||||
AbstractMsTypeApplier applier =
|
||||
MsTypeApplier applier =
|
||||
applicator.getTypeApplier(RecordNumber.typeRecordNumber(indexNumber));
|
||||
applier.apply();
|
||||
}
|
||||
|
@ -376,10 +395,10 @@ public class PdbResearch {
|
|||
return false;
|
||||
}
|
||||
AbstractMsSymbol symbol = iter.peek(); //temporary during development
|
||||
AbstractMsSymbolApplier applier = applicator.getSymbolApplier(iter);
|
||||
MsSymbolApplier applier = applicator.getSymbolApplier(iter);
|
||||
if (applier instanceof TypedefSymbolApplier) {
|
||||
TypedefSymbolApplier typedefApplier = (TypedefSymbolApplier) applier;
|
||||
AbstractMsTypeApplier typeApplier =
|
||||
MsTypeApplier typeApplier =
|
||||
applicator.getTypeApplier(typedefApplier.getTypeRecordNumber());
|
||||
System.out.println("UDT " + typedefApplier.getName() + " depends on " +
|
||||
typeApplier.getMsType().toString());
|
||||
|
@ -394,7 +413,7 @@ public class PdbResearch {
|
|||
}
|
||||
else if (applier instanceof DataSymbolApplier) {
|
||||
DataSymbolApplier dataSymbolApplier = (DataSymbolApplier) applier;
|
||||
AbstractMsTypeApplier typeApplier = dataSymbolApplier.getTypeApplier();
|
||||
MsTypeApplier typeApplier = dataSymbolApplier.getTypeApplier();
|
||||
childWalkType(moduleNumber, typeApplier);
|
||||
}
|
||||
else if (applier instanceof FunctionSymbolApplier) {
|
||||
|
@ -414,7 +433,7 @@ public class PdbResearch {
|
|||
}
|
||||
|
||||
//==============================================================================================
|
||||
static private boolean childWalkType(int moduleNumber, AbstractMsTypeApplier applier) {
|
||||
static private boolean childWalkType(int moduleNumber, MsTypeApplier applier) {
|
||||
int b = 1;
|
||||
b = b + 1;
|
||||
if (applier instanceof AbstractFunctionTypeApplier) {
|
||||
|
@ -427,7 +446,8 @@ public class PdbResearch {
|
|||
//==============================================================================================
|
||||
//==============================================================================================
|
||||
//==============================================================================================
|
||||
static void studyDataTypeConflicts(PdbApplicator applicator, TaskMonitor monitor) {
|
||||
static void studyDataTypeConflicts(PdbApplicator applicator, TaskMonitor monitor)
|
||||
throws CancelledException {
|
||||
DataTypeConflictHandler handler =
|
||||
DataTypeConflictHandler.REPLACE_EMPTY_STRUCTS_OR_RENAME_AND_ADD_HANDLER;
|
||||
DataTypeManager dtm = applicator.getDataTypeManager();
|
||||
|
@ -482,7 +502,8 @@ public class PdbResearch {
|
|||
return composite;
|
||||
}
|
||||
|
||||
private static void fillComposite(Composite composite, TaskMonitor monitor, DataType extra) {
|
||||
private static void fillComposite(Composite composite, TaskMonitor monitor, DataType extra)
|
||||
throws CancelledException {
|
||||
List<DefaultTestPdbMember> members = new ArrayList<>();
|
||||
DefaultTestPdbMember member;
|
||||
int size = 8;
|
||||
|
@ -496,14 +517,9 @@ public class PdbResearch {
|
|||
members.add(member);
|
||||
size += extra.getLength();
|
||||
}
|
||||
try {
|
||||
if (!DefaultCompositeMember.applyDataTypeMembers(composite, false, size, members,
|
||||
msg -> reconstructionWarn(msg), monitor)) {
|
||||
((Structure) composite).deleteAll();
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
Msg.info(null, "Research exception thrown");
|
||||
if (!DefaultCompositeMember.applyDataTypeMembers(composite, false, size, members,
|
||||
msg -> reconstructionWarn(msg), monitor)) {
|
||||
((Structure) composite).deleteAll();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -674,7 +690,7 @@ public class PdbResearch {
|
|||
!((AbstractPublic32MsSymbol) symbol).isFunction()) {
|
||||
return;
|
||||
}
|
||||
Address address = applicator.reladdr((AbstractPublicMsSymbol) symbol);
|
||||
Address address = applicator.getAddress((AbstractPublicMsSymbol) symbol);
|
||||
String name = ((AbstractPublicMsSymbol) symbol).getName();
|
||||
String demangledName = getDemangledQualifiedName(name);
|
||||
if (demangledName != null) {
|
||||
|
@ -689,7 +705,7 @@ public class PdbResearch {
|
|||
private static void processProcedureSymbol(PdbApplicator applicator,
|
||||
Map<Address, List<Stuff>> map, AbstractMsSymbol symbol) {
|
||||
if (symbol instanceof AbstractProcedureMsSymbol) {
|
||||
Address address = applicator.reladdr((AbstractProcedureMsSymbol) symbol);
|
||||
Address address = applicator.getAddress((AbstractProcedureMsSymbol) symbol);
|
||||
String name = ((AbstractProcedureMsSymbol) symbol).getName();
|
||||
Stuff stuff = new Stuff(symbol, name, What.GLOBAL);
|
||||
addStuff(map, address, stuff);
|
||||
|
@ -717,7 +733,7 @@ public class PdbResearch {
|
|||
|
||||
/**
|
||||
* Gets a demangles the name and returns the qualified name. Returns null if not mangled
|
||||
* or if error in demangling.
|
||||
* or if error in demangling.
|
||||
* @param mangledString the mangled string to be decoded
|
||||
* @return the qualified name of the demangled string or null if not mangled or error.
|
||||
*/
|
||||
|
@ -772,7 +788,7 @@ public class PdbResearch {
|
|||
|
||||
//==============================================================================================
|
||||
//==============================================================================================
|
||||
static void studyCompositeFwdRefDef(AbstractPdb pdb, TaskMonitor monitor)
|
||||
static void studyCompositeForwardReferenceAndDefinition(AbstractPdb pdb, TaskMonitor monitor)
|
||||
throws CancelledException {
|
||||
int indexNumber = pdb.getTypeProgramInterface().getTypeIndexMin();
|
||||
int indexLimit = pdb.getTypeProgramInterface().getTypeIndexMaxExclusive();
|
||||
|
@ -793,27 +809,27 @@ public class PdbResearch {
|
|||
MsProperty p;
|
||||
String ps;
|
||||
int c;
|
||||
boolean isFwdRef = false;
|
||||
boolean isForwardReference = false;
|
||||
Map<Integer, Set<String>> map = new HashMap<>();
|
||||
if (type instanceof AbstractCompositeMsType) {
|
||||
AbstractCompositeMsType compType = (AbstractCompositeMsType) type;
|
||||
c = compType.getNumElements();
|
||||
p = compType.getMsProperty();
|
||||
isFwdRef = p.isForwardReference();
|
||||
if (c == 0 && !isFwdRef) {
|
||||
isForwardReference = p.isForwardReference();
|
||||
if (c == 0 && !isForwardReference) {
|
||||
int a = 1;
|
||||
a = a + 1;
|
||||
// For PDBs that we have looked at, if count is zero
|
||||
// for a fwdref, then the field list record number is zero;
|
||||
// if count is zero for a def, then, the field list record
|
||||
// for a forward reference, then the field list record number is zero;
|
||||
// if count is zero for a definition, then, the field list record
|
||||
// number refers to an actual field list.
|
||||
// So... seems we can trust fwdref and ignore count.
|
||||
// So... seems we can trust forward reference and ignore count.
|
||||
if (compType.getFieldDescriptorListRecordNumber() == RecordNumber.NO_TYPE) {
|
||||
int b = 1;
|
||||
b = b + 1;
|
||||
}
|
||||
}
|
||||
else if (c != 0 && isFwdRef) {
|
||||
else if (c != 0 && isForwardReference) {
|
||||
int a = 1;
|
||||
a = a + 1;
|
||||
}
|
||||
|
@ -829,7 +845,8 @@ public class PdbResearch {
|
|||
Set<String> set = new HashSet<>();
|
||||
set.add(ps);
|
||||
map.put(c, set);
|
||||
PdbLog.message("----------\n" + name + "\n" + c + (isFwdRef ? " fwdref" : ""));
|
||||
PdbLog.message(
|
||||
"----------\n" + name + "\n" + c + (isForwardReference ? " fwdref" : ""));
|
||||
//System.out.println("----------\n" + name + "\n" + c);
|
||||
int innerIndexNumber = indexNumber + 1;
|
||||
while (innerIndexNumber < indexLimit) {
|
||||
|
@ -840,25 +857,26 @@ public class PdbResearch {
|
|||
String innerName = getSpecialRecordStart(innerType);
|
||||
if (name.equals(innerName)) {
|
||||
covered[innerIndexNumber] = true;
|
||||
isFwdRef = false;
|
||||
isForwardReference = false;
|
||||
if (type instanceof AbstractCompositeMsType) {
|
||||
AbstractCompositeMsType compType =
|
||||
(AbstractCompositeMsType) innerType;
|
||||
c = compType.getNumElements();
|
||||
p = compType.getMsProperty();
|
||||
isFwdRef = p.isForwardReference();
|
||||
if (c == 0 && !isFwdRef) {
|
||||
isForwardReference = p.isForwardReference();
|
||||
if (c == 0 && !isForwardReference) {
|
||||
// For PDBs that we have looked at, if count is zero
|
||||
// for a fwdref, then the field list record number is zero;
|
||||
// if count is zero for a def, then, the field list record
|
||||
// number refers to an actual field list.
|
||||
// So... seems we can trust fwdref and ignore count.
|
||||
// for a forward reference, then the field list record
|
||||
// number is zero; if count is zero for a definition, then,
|
||||
// the field list record number refers to an actual field
|
||||
// list. So... seems we can trust forward reference and
|
||||
// ignore count.
|
||||
if (compType.getFieldDescriptorListRecordNumber() == RecordNumber.NO_TYPE) {
|
||||
int a = 1;
|
||||
a = a + 1;
|
||||
}
|
||||
}
|
||||
else if (c != 0 && isFwdRef) {
|
||||
else if (c != 0 && isForwardReference) {
|
||||
int a = 1;
|
||||
a = a + 1;
|
||||
}
|
||||
|
@ -885,8 +903,8 @@ public class PdbResearch {
|
|||
else {
|
||||
message = " <-- repeat";
|
||||
}
|
||||
PdbLog.message(c + (isFwdRef ? " fwdref" : "") + message);
|
||||
if (c == 0 && isFwdRef) {
|
||||
PdbLog.message(c + (isForwardReference ? " fwdref" : "") + message);
|
||||
if (c == 0 && isForwardReference) {
|
||||
PdbLog.message("Orig: " + ps + "\nNew: " + psi);
|
||||
}
|
||||
//System.out.println(c + message);
|
||||
|
|
|
@ -33,7 +33,6 @@ import ghidra.util.task.TaskMonitor;
|
|||
/**
|
||||
* Manages virtual base table lookup for PDB classes.
|
||||
*/
|
||||
|
||||
public class PdbVbtManager extends VbtManager {
|
||||
|
||||
Map<String, Address> addressByMangledName;
|
||||
|
@ -75,7 +74,7 @@ public class PdbVbtManager extends VbtManager {
|
|||
AbstractPublicMsSymbol pubSymbol = (AbstractPublicMsSymbol) symbol;
|
||||
String name = pubSymbol.getName();
|
||||
if (name.startsWith("??_8")) {
|
||||
Address address = applicator.reladdr(pubSymbol);
|
||||
Address address = applicator.getAddress(pubSymbol);
|
||||
myAddressByMangledName.put(name, address);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,10 +26,15 @@ import ghidra.util.exception.CancelledException;
|
|||
/**
|
||||
* Applier for {@link PeCoffGroupMsSymbol} symbols.
|
||||
*/
|
||||
public class PeCoffGroupSymbolApplier extends AbstractMsSymbolApplier {
|
||||
public class PeCoffGroupSymbolApplier extends MsSymbolApplier {
|
||||
|
||||
private PeCoffGroupMsSymbol symbol;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param applicator the {@link PdbApplicator} for which we are working.
|
||||
* @param iter the Iterator containing the symbol sequence being processed
|
||||
*/
|
||||
public PeCoffGroupSymbolApplier(PdbApplicator applicator, AbstractMsSymbolIterator iter) {
|
||||
super(applicator, iter);
|
||||
AbstractMsSymbol abstractSymbol = iter.next();
|
||||
|
@ -41,9 +46,9 @@ public class PeCoffGroupSymbolApplier extends AbstractMsSymbolApplier {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void apply() throws PdbException, CancelledException {
|
||||
void apply() throws PdbException, CancelledException {
|
||||
applicator.addMemoryGroupRefinement(symbol);
|
||||
Address symbolAddress = applicator.reladdr(symbol);
|
||||
Address symbolAddress = applicator.getAddress(symbol);
|
||||
if (!Address.NO_ADDRESS.equals(symbolAddress)) {
|
||||
boolean forcePrimary = applicator.shouldForcePrimarySymbol(symbolAddress, false);
|
||||
String name = symbol.getName();
|
||||
|
@ -59,7 +64,7 @@ public class PeCoffGroupSymbolApplier extends AbstractMsSymbolApplier {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void applyTo(AbstractMsSymbolApplier applyToApplier) {
|
||||
void applyTo(MsSymbolApplier applyToApplier) {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
|
|
|
@ -25,10 +25,15 @@ import ghidra.util.exception.CancelledException;
|
|||
/**
|
||||
* Applier for {@link PeCoffSectionMsSymbol} symbols.
|
||||
*/
|
||||
public class PeCoffSectionSymbolApplier extends AbstractMsSymbolApplier {
|
||||
public class PeCoffSectionSymbolApplier extends MsSymbolApplier {
|
||||
|
||||
private PeCoffSectionMsSymbol symbol;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param applicator the {@link PdbApplicator} for which we are working.
|
||||
* @param iter the Iterator containing the symbol sequence being processed
|
||||
*/
|
||||
public PeCoffSectionSymbolApplier(PdbApplicator applicator, AbstractMsSymbolIterator iter) {
|
||||
super(applicator, iter);
|
||||
AbstractMsSymbol abstractSymbol = iter.next();
|
||||
|
@ -40,7 +45,7 @@ public class PeCoffSectionSymbolApplier extends AbstractMsSymbolApplier {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void apply() throws PdbException, CancelledException {
|
||||
void apply() throws PdbException, CancelledException {
|
||||
int sectionNum = symbol.getSectionNumber();
|
||||
long realAddress = symbol.getRva();
|
||||
symbol.getLength();
|
||||
|
@ -52,7 +57,7 @@ public class PeCoffSectionSymbolApplier extends AbstractMsSymbolApplier {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void applyTo(AbstractMsSymbolApplier applyToApplier) {
|
||||
void applyTo(MsSymbolApplier applyToApplier) {
|
||||
// Do nothing
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,43 +26,33 @@ import ghidra.util.exception.CancelledException;
|
|||
/**
|
||||
* Applier for {@link AbstractPointerMsType} types.
|
||||
*/
|
||||
public class PointerTypeApplier extends AbstractMsTypeApplier {
|
||||
|
||||
private static AbstractMsType validateType(AbstractMsType type)
|
||||
throws IllegalArgumentException {
|
||||
if (!(type instanceof AbstractPointerMsType)) {
|
||||
throw new IllegalArgumentException(
|
||||
"PDB Incorrectly applying " + type.getClass().getSimpleName() + " to " +
|
||||
PointerTypeApplier.class.getSimpleName());
|
||||
}
|
||||
return type;
|
||||
}
|
||||
public class PointerTypeApplier extends MsTypeApplier {
|
||||
|
||||
private boolean isFunctionPointer = false;
|
||||
|
||||
/**
|
||||
* Constructor for pointer type applier, for transforming a enum into a
|
||||
* Ghidra DataType.
|
||||
* Ghidra DataType.
|
||||
* @param applicator {@link PdbApplicator} for which this class is working.
|
||||
* @param msType {@link AbstractPointerMsType} to process
|
||||
* @throws IllegalArgumentException Upon invalid arguments.
|
||||
*/
|
||||
public PointerTypeApplier(PdbApplicator applicator, AbstractMsType msType)
|
||||
public PointerTypeApplier(PdbApplicator applicator, AbstractPointerMsType msType)
|
||||
throws IllegalArgumentException {
|
||||
super(applicator, validateType(msType));
|
||||
super(applicator, msType);
|
||||
}
|
||||
|
||||
public boolean isFunctionPointer() {
|
||||
boolean isFunctionPointer() {
|
||||
return isFunctionPointer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BigInteger getSize() {
|
||||
BigInteger getSize() {
|
||||
return ((AbstractPointerMsType) msType).getSize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply() throws PdbException, CancelledException {
|
||||
void apply() throws PdbException, CancelledException {
|
||||
if (msType instanceof DummyMsType) {
|
||||
dataType = new PointerDataType(applicator.getDataTypeManager());
|
||||
}
|
||||
|
@ -72,12 +62,12 @@ public class PointerTypeApplier extends AbstractMsTypeApplier {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void resolve() {
|
||||
void resolve() {
|
||||
// Do not resolve pointer types... will be resolved naturally, as needed
|
||||
}
|
||||
|
||||
public AbstractMsTypeApplier getUnmodifiedUnderlyingTypeApplier() {
|
||||
AbstractMsTypeApplier thisUnderlyingTypeApplier =
|
||||
MsTypeApplier getUnmodifiedUnderlyingTypeApplier() {
|
||||
MsTypeApplier thisUnderlyingTypeApplier =
|
||||
applicator.getTypeApplier(((AbstractPointerMsType) msType).getUnderlyingRecordNumber());
|
||||
|
||||
// TODO: does not recurse below one level of modifiers... consider doing a recursion.
|
||||
|
@ -91,7 +81,7 @@ public class PointerTypeApplier extends AbstractMsTypeApplier {
|
|||
}
|
||||
|
||||
private DataType applyAbstractPointerMsType(AbstractPointerMsType type) {
|
||||
AbstractMsTypeApplier underlyingApplier =
|
||||
MsTypeApplier underlyingApplier =
|
||||
applicator.getTypeApplier(type.getUnderlyingRecordNumber());
|
||||
|
||||
if (underlyingApplier instanceof ProcedureTypeApplier) {
|
||||
|
|
|
@ -17,49 +17,36 @@ package ghidra.app.util.pdb.pdbapplicator;
|
|||
|
||||
import java.math.BigInteger;
|
||||
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.type.AbstractMsType;
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.type.PrimitiveMsType;
|
||||
import ghidra.program.model.data.DataType;
|
||||
|
||||
/**
|
||||
* Applier for {@link PrimitiveMsType} types.
|
||||
*/
|
||||
public class PrimitiveTypeApplier extends AbstractMsTypeApplier {
|
||||
|
||||
private static AbstractMsType validateType(AbstractMsType type)
|
||||
throws IllegalArgumentException {
|
||||
if (!(type instanceof PrimitiveMsType)) {
|
||||
throw new IllegalArgumentException(
|
||||
"PDB Incorrectly applying " + type.getClass().getSimpleName() + " to " +
|
||||
PrimitiveTypeApplier.class.getSimpleName());
|
||||
}
|
||||
return type;
|
||||
}
|
||||
public class PrimitiveTypeApplier extends MsTypeApplier {
|
||||
|
||||
/**
|
||||
* Constructor for primitive type applier, for transforming a primitive into a
|
||||
* Ghidra DataType.
|
||||
* Ghidra DataType.
|
||||
* @param applicator {@link PdbApplicator} for which this class is working.
|
||||
* @param msType {@link PrimitiveMsType} to process.
|
||||
* @throws IllegalArgumentException Upon invalid arguments.
|
||||
*/
|
||||
public PrimitiveTypeApplier(PdbApplicator applicator, AbstractMsType msType)
|
||||
throws IllegalArgumentException {
|
||||
super(applicator, validateType(msType));
|
||||
public PrimitiveTypeApplier(PdbApplicator applicator, PrimitiveMsType msType) {
|
||||
super(applicator, msType);
|
||||
apply(); // Only apply in constructor for primitives
|
||||
}
|
||||
|
||||
@Override
|
||||
public BigInteger getSize() {
|
||||
BigInteger getSize() {
|
||||
return BigInteger.valueOf(((PrimitiveMsType) msType).getTypeSize());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply() {
|
||||
void apply() {
|
||||
dataType = applyPrimitiveMsType((PrimitiveMsType) msType);
|
||||
}
|
||||
|
||||
public boolean isNoType() {
|
||||
boolean isNoType() {
|
||||
return (((PrimitiveMsType) msType).getNumber() == 0);
|
||||
}
|
||||
|
||||
|
|
|
@ -19,7 +19,8 @@ import java.math.BigInteger;
|
|||
|
||||
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.app.util.bin.format.pdb2.pdbreader.type.AbstractProcedureMsType;
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.type.CallingConvention;
|
||||
import ghidra.program.model.data.DataType;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
|
||||
|
@ -28,30 +29,20 @@ import ghidra.util.exception.CancelledException;
|
|||
*/
|
||||
public class ProcedureTypeApplier extends AbstractFunctionTypeApplier {
|
||||
|
||||
private static AbstractMsType validateType(AbstractMsType type)
|
||||
throws IllegalArgumentException {
|
||||
if (!(type instanceof AbstractProcedureMsType)) {
|
||||
throw new IllegalArgumentException(
|
||||
"PDB Incorrectly applying " + type.getClass().getSimpleName() + " to " +
|
||||
ProcedureTypeApplier.class.getSimpleName());
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for the applicator that applies {@link AbstractProcedureMsType},
|
||||
* transforming it into a Ghidra {@link DataType}.
|
||||
* transforming it into a Ghidra {@link DataType}.
|
||||
* @param applicator {@link PdbApplicator} for which this class is working.
|
||||
* @param msType {@link AbstractProcedureMsType} to processes.
|
||||
* @throws IllegalArgumentException Upon invalid arguments.
|
||||
*/
|
||||
public ProcedureTypeApplier(PdbApplicator applicator, AbstractMsType msType)
|
||||
public ProcedureTypeApplier(PdbApplicator applicator, AbstractProcedureMsType msType)
|
||||
throws IllegalArgumentException {
|
||||
super(applicator, validateType(msType));
|
||||
super(applicator, msType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BigInteger getSize() {
|
||||
BigInteger getSize() {
|
||||
return BigInteger.ZERO;
|
||||
}
|
||||
|
||||
|
@ -76,7 +67,7 @@ public class ProcedureTypeApplier extends AbstractFunctionTypeApplier {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void apply() throws PdbException, CancelledException {
|
||||
void apply() throws PdbException, CancelledException {
|
||||
applyFunction(getCallingConvention(), hasThisPointer());
|
||||
|
||||
// AbstractProcedureMsType procType = (AbstractProcedureMsType) msType;
|
||||
|
|
|
@ -18,25 +18,28 @@ package ghidra.app.util.pdb.pdbapplicator;
|
|||
import java.util.List;
|
||||
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.PdbException;
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.PdbLog;
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.symbol.AbstractMsSymbol;
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.symbol.AbstractPublicMsSymbol;
|
||||
import ghidra.app.util.pdb.pdbapplicator.SymbolGroup.AbstractMsSymbolIterator;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.symbol.Symbol;
|
||||
import ghidra.util.Msg;
|
||||
import ghidra.util.exception.AssertException;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
|
||||
/**
|
||||
* Applier for {@link AbstractPublicMsSymbol} symbols.
|
||||
*/
|
||||
public class PublicSymbolApplier extends AbstractMsSymbolApplier {
|
||||
public class PublicSymbolApplier extends MsSymbolApplier {
|
||||
|
||||
private AbstractPublicMsSymbol symbol;
|
||||
private Address symbolAddress = null;
|
||||
private Address existingSymbolAddress = null;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param applicator the {@link PdbApplicator} for which we are working.
|
||||
* @param iter the Iterator containing the symbol sequence being processed
|
||||
*/
|
||||
public PublicSymbolApplier(PdbApplicator applicator, AbstractMsSymbolIterator iter) {
|
||||
super(applicator, iter);
|
||||
AbstractMsSymbol abstractSymbol = iter.next();
|
||||
|
@ -48,14 +51,14 @@ public class PublicSymbolApplier extends AbstractMsSymbolApplier {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void applyTo(AbstractMsSymbolApplier applyToApplier) {
|
||||
void applyTo(MsSymbolApplier applyToApplier) {
|
||||
// Do nothing.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply() throws CancelledException, PdbException {
|
||||
void apply() throws CancelledException, PdbException {
|
||||
|
||||
symbolAddress = applicator.reladdr(symbol);
|
||||
symbolAddress = applicator.getAddress(symbol);
|
||||
if (!Address.NO_ADDRESS.equals(symbolAddress)) {
|
||||
|
||||
if (getName().startsWith("?")) { // mangled... should be unique
|
||||
|
@ -79,9 +82,7 @@ public class PublicSymbolApplier extends AbstractMsSymbolApplier {
|
|||
}
|
||||
}
|
||||
else {
|
||||
String message = "Could not apply symbol at NO_ADDRESS: " + symbol.getName();
|
||||
Msg.info(this, message);
|
||||
PdbLog.message(message);
|
||||
pdbLogAndInfoMessage(this, "Could not apply symbol at NO_ADDRESS: " + symbol.getName());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -25,10 +25,15 @@ import ghidra.util.exception.CancelledException;
|
|||
/**
|
||||
* Applier for {@link AbstractReferenceMsSymbol} symbols.
|
||||
*/
|
||||
public class ReferenceSymbolApplier extends AbstractMsSymbolApplier {
|
||||
public class ReferenceSymbolApplier extends MsSymbolApplier {
|
||||
|
||||
private AbstractReferenceMsSymbol symbol;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param applicator the {@link PdbApplicator} for which we are working.
|
||||
* @param iter the Iterator containing the symbol sequence being processed
|
||||
*/
|
||||
public ReferenceSymbolApplier(PdbApplicator applicator, AbstractMsSymbolIterator iter) {
|
||||
super(applicator, iter);
|
||||
AbstractMsSymbol abstractSymbol = iter.next();
|
||||
|
@ -40,12 +45,12 @@ public class ReferenceSymbolApplier extends AbstractMsSymbolApplier {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void applyTo(AbstractMsSymbolApplier applyToApplier) {
|
||||
void applyTo(MsSymbolApplier applyToApplier) {
|
||||
// Do nothing.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply() throws CancelledException, PdbException {
|
||||
void apply() throws CancelledException, PdbException {
|
||||
// Potential recursive call via applicator.procSym().
|
||||
AbstractMsSymbolIterator refIter = getInitializedReferencedSymbolGroup().iterator();
|
||||
applicator.procSym(refIter);
|
||||
|
|
|
@ -18,7 +18,6 @@ package ghidra.app.util.pdb.pdbapplicator;
|
|||
import java.util.Objects;
|
||||
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.PdbException;
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.PdbLog;
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.symbol.AbstractMsSymbol;
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.symbol.AbstractRegisterRelativeAddressMsSymbol;
|
||||
import ghidra.app.util.pdb.pdbapplicator.SymbolGroup.AbstractMsSymbolIterator;
|
||||
|
@ -26,16 +25,20 @@ import ghidra.program.model.data.DataType;
|
|||
import ghidra.program.model.lang.Register;
|
||||
import ghidra.program.model.listing.*;
|
||||
import ghidra.program.model.symbol.SourceType;
|
||||
import ghidra.util.Msg;
|
||||
import ghidra.util.exception.*;
|
||||
|
||||
/**
|
||||
* Applier for {@link AbstractRegisterRelativeAddressMsSymbol} symbols.
|
||||
*/
|
||||
public class RegisterRelativeSymbolApplier extends AbstractMsSymbolApplier {
|
||||
public class RegisterRelativeSymbolApplier extends MsSymbolApplier {
|
||||
|
||||
private AbstractRegisterRelativeAddressMsSymbol symbol;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param applicator the {@link PdbApplicator} for which we are working.
|
||||
* @param iter the Iterator containing the symbol sequence being processed
|
||||
*/
|
||||
public RegisterRelativeSymbolApplier(PdbApplicator applicator, AbstractMsSymbolIterator iter) {
|
||||
super(applicator, iter);
|
||||
AbstractMsSymbol abstractSymbol = iter.next();
|
||||
|
@ -47,15 +50,13 @@ public class RegisterRelativeSymbolApplier extends AbstractMsSymbolApplier {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void apply() throws PdbException, CancelledException {
|
||||
String message = "Cannot apply " + this.getClass().getSimpleName() + " directly to program";
|
||||
Msg.info(this, message);
|
||||
PdbLog.message(message);
|
||||
void apply() throws PdbException, CancelledException {
|
||||
pdbLogAndInfoMessage(this,
|
||||
"Cannot apply " + this.getClass().getSimpleName() + " directly to program");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyTo(AbstractMsSymbolApplier applyToApplier)
|
||||
throws PdbException, CancelledException {
|
||||
void applyTo(MsSymbolApplier applyToApplier) throws PdbException, CancelledException {
|
||||
if (!applicator.getPdbApplicatorOptions().applyFunctionVariables()) {
|
||||
return;
|
||||
}
|
||||
|
@ -103,7 +104,7 @@ public class RegisterRelativeSymbolApplier extends AbstractMsSymbolApplier {
|
|||
// }
|
||||
int offset = (int) (relativeOffset & 0xffffffffL);
|
||||
|
||||
AbstractMsTypeApplier dataTypeApplier =
|
||||
MsTypeApplier dataTypeApplier =
|
||||
applicator.getTypeApplier(symbol.getTypeRecordNumber());
|
||||
DataType dt = dataTypeApplier.getDataType();
|
||||
if (dt != null) {
|
||||
|
@ -144,7 +145,7 @@ public class RegisterRelativeSymbolApplier extends AbstractMsSymbolApplier {
|
|||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
catch (InvalidInputException | DuplicateNameException e) {
|
||||
applicator.appendLogMsg("Unable to create stack variable " + symbol.getName() +
|
||||
" at offset " + offset + " in " + function.getName());
|
||||
return false;
|
||||
|
|
|
@ -15,7 +15,8 @@
|
|||
*/
|
||||
package ghidra.app.util.pdb.pdbapplicator;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import ghidra.app.cmd.comments.SetCommentCmd;
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.PdbException;
|
||||
|
@ -31,7 +32,7 @@ import ghidra.util.exception.CancelledException;
|
|||
*/
|
||||
// TODO: Need to evaluate relationship to function symbols.
|
||||
// TODO: Need to create anonymous name for this as a function?
|
||||
public class SeparatedCodeSymbolApplier extends AbstractMsSymbolApplier {
|
||||
public class SeparatedCodeSymbolApplier extends MsSymbolApplier {
|
||||
|
||||
private SeparatedCodeFromCompilerSupportMsSymbol symbol;
|
||||
|
||||
|
@ -43,7 +44,7 @@ public class SeparatedCodeSymbolApplier extends AbstractMsSymbolApplier {
|
|||
private int symbolBlockNestingLevel;
|
||||
private Address currentBlockAddress;
|
||||
|
||||
private List<AbstractMsSymbolApplier> allAppliers = new ArrayList<>();
|
||||
private List<MsSymbolApplier> allAppliers = new ArrayList<>();
|
||||
|
||||
private static AbstractMsSymbolIterator validateSymbol(AbstractMsSymbolIterator iter) {
|
||||
if (!(iter.peek() instanceof SeparatedCodeFromCompilerSupportMsSymbol)) {
|
||||
|
@ -52,13 +53,19 @@ public class SeparatedCodeSymbolApplier extends AbstractMsSymbolApplier {
|
|||
return iter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param applicator the {@link PdbApplicator} for which we are working.
|
||||
* @param iter the Iterator containing the symbol sequence being processed
|
||||
* @throws CancelledException upon user cancellation
|
||||
*/
|
||||
public SeparatedCodeSymbolApplier(PdbApplicator applicator, AbstractMsSymbolIterator iter)
|
||||
throws CancelledException, NoSuchElementException {
|
||||
throws CancelledException {
|
||||
super(applicator, validateSymbol(iter));
|
||||
|
||||
symbol = (SeparatedCodeFromCompilerSupportMsSymbol) iter.next();
|
||||
|
||||
specifiedAddress = applicator.reladdr(symbol);
|
||||
specifiedAddress = applicator.getAddress(symbol);
|
||||
|
||||
// Make up name. TODO: decide if need better anonymous name
|
||||
craftedName = String.format("CompilerSeparatedCode%s", specifiedAddress);
|
||||
|
@ -72,7 +79,7 @@ public class SeparatedCodeSymbolApplier extends AbstractMsSymbolApplier {
|
|||
|
||||
while (notDone()) {
|
||||
applicator.checkCanceled();
|
||||
AbstractMsSymbolApplier applier = applicator.getSymbolApplier(iter);
|
||||
MsSymbolApplier applier = applicator.getSymbolApplier(iter);
|
||||
if (!(applier instanceof EndSymbolApplier)) {
|
||||
Msg.info(this, "Unexpected applier in " + getClass().getSimpleName() + ": " +
|
||||
applier.getClass().getSimpleName());
|
||||
|
@ -83,17 +90,17 @@ public class SeparatedCodeSymbolApplier extends AbstractMsSymbolApplier {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void manageBlockNesting(AbstractMsSymbolApplier applierParam) {
|
||||
void manageBlockNesting(MsSymbolApplier applierParam) {
|
||||
beginBlock(specifiedAddress);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyTo(AbstractMsSymbolApplier applyToApplier) {
|
||||
void applyTo(MsSymbolApplier applyToApplier) {
|
||||
// Do nothing.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply() throws PdbException, CancelledException {
|
||||
void apply() throws PdbException, CancelledException {
|
||||
// DO NOTHING FOR NOW. TODO: should we have a configuration option?
|
||||
// Note: these comments can be noise in the decompiler an code browser
|
||||
setComments(false);
|
||||
|
@ -119,7 +126,7 @@ public class SeparatedCodeSymbolApplier extends AbstractMsSymbolApplier {
|
|||
return (symbolBlockNestingLevel > 0) && iter.hasNext();
|
||||
}
|
||||
|
||||
public int endBlock() {
|
||||
int endBlock() {
|
||||
if (--symbolBlockNestingLevel < 0) {
|
||||
applicator.appendLogMsg("Block Nesting went negative at " + specifiedAddress);
|
||||
}
|
||||
|
|
|
@ -15,17 +15,19 @@
|
|||
*/
|
||||
package ghidra.app.util.pdb.pdbapplicator;
|
||||
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.symbol.*;
|
||||
import ghidra.app.util.pdb.pdbapplicator.SymbolGroup.AbstractMsSymbolIterator;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
|
||||
public class SymbolApplierParser {
|
||||
/**
|
||||
* Pseudo-factory for creating the {@link MsSymbolApplier} for the {@link AbstractMsSymbol}
|
||||
* indicated by the {@link AbstractMsSymbolIterator}.
|
||||
*/
|
||||
public class SymbolApplierFactory {
|
||||
|
||||
private PdbApplicator applicator;
|
||||
|
||||
SymbolApplierParser(PdbApplicator applicator) {
|
||||
SymbolApplierFactory(PdbApplicator applicator) {
|
||||
this.applicator = applicator;
|
||||
}
|
||||
|
||||
|
@ -34,15 +36,14 @@ public class SymbolApplierParser {
|
|||
// the AbstractMsSymbol (do one for AbstractMsType as well)? Symbols are different in that
|
||||
// we are using SymbolGroup as a member instead of MsType.
|
||||
|
||||
AbstractMsSymbolApplier getSymbolApplier(AbstractMsSymbolIterator iter)
|
||||
throws CancelledException, NoSuchElementException {
|
||||
MsSymbolApplier getSymbolApplier(AbstractMsSymbolIterator iter) throws CancelledException {
|
||||
|
||||
AbstractMsSymbol symbol = iter.peek();
|
||||
if (symbol == null) {
|
||||
applicator.appendLogMsg("PDB Warning: No AbstractMsSymbol");
|
||||
return null;
|
||||
}
|
||||
AbstractMsSymbolApplier applier = null;
|
||||
MsSymbolApplier applier = null;
|
||||
|
||||
switch (symbol.getPdbId()) {
|
||||
// // 0x0000 block
|
|
@ -23,8 +23,8 @@ import ghidra.app.util.bin.format.pdb2.pdbreader.symbol.AbstractMsSymbol;
|
|||
|
||||
/**
|
||||
* This class represents a particular group of Symbols that came from the same PDB stream. This
|
||||
* wraps the internal structure and offers mechanisms for accessing records. It does not map
|
||||
* directly to an MSFT structure.
|
||||
* wraps the internal structure and offers mechanisms for accessing records. It does not map
|
||||
* directly to an MSFT structure.
|
||||
*/
|
||||
public class SymbolGroup {
|
||||
|
||||
|
@ -37,7 +37,7 @@ public class SymbolGroup {
|
|||
* Constructor. The starting offset is set to zero.
|
||||
* @param symbolsByOffset the Map used to initialize the constructor.
|
||||
* @param moduleNumber The Module number corresponding to the initializing Map
|
||||
* (0 for public/global Map).
|
||||
* (0 for public/global Map).
|
||||
*/
|
||||
public SymbolGroup(Map<Long, AbstractMsSymbol> symbolsByOffset, int moduleNumber) {
|
||||
this(symbolsByOffset, moduleNumber, 0);
|
||||
|
@ -47,7 +47,7 @@ public class SymbolGroup {
|
|||
* Constructor.
|
||||
* @param symbolsByOffset the Map used to initialize the constructor.
|
||||
* @param moduleNumber The Module number corresponding to the initializing Map
|
||||
* (0 for public/global Map).
|
||||
* (0 for public/global Map).
|
||||
* @param offset the offset location to start.
|
||||
*/
|
||||
public SymbolGroup(Map<Long, AbstractMsSymbol> symbolsByOffset, int moduleNumber, long offset) {
|
||||
|
@ -60,7 +60,7 @@ public class SymbolGroup {
|
|||
* Returns the list of symbols. These may not be in the order that they were seen.
|
||||
* @return the list of symbols.
|
||||
*/
|
||||
public List<AbstractMsSymbol> getSymbols() {
|
||||
List<AbstractMsSymbol> getSymbols() {
|
||||
return new ArrayList<>(symbolsByOffset.values());
|
||||
}
|
||||
|
||||
|
@ -68,7 +68,7 @@ public class SymbolGroup {
|
|||
* Returns the module number.
|
||||
* @return the module number.
|
||||
*/
|
||||
public int getModuleNumber() {
|
||||
int getModuleNumber() {
|
||||
return moduleNumber;
|
||||
|
||||
}
|
||||
|
@ -77,7 +77,7 @@ public class SymbolGroup {
|
|||
* Returns the number of symbols.
|
||||
* @return the number of symbols.
|
||||
*/
|
||||
public int size() {
|
||||
int size() {
|
||||
return symbolsByOffset.size();
|
||||
}
|
||||
|
||||
|
@ -85,7 +85,7 @@ public class SymbolGroup {
|
|||
* Returns the list of symbol offsets in the order they were seen.
|
||||
* @return the list of symbol offsets.
|
||||
*/
|
||||
public List<Long> getOrderedOffsets() {
|
||||
List<Long> getOrderedOffsets() {
|
||||
return new ArrayList<>(symbolsByOffset.keySet());
|
||||
}
|
||||
|
||||
|
@ -93,7 +93,7 @@ public class SymbolGroup {
|
|||
* Returns the set of symbol offsets.
|
||||
* @return the set of symbol offsets.
|
||||
*/
|
||||
public Set<Long> getOffsets() {
|
||||
Set<Long> getOffsets() {
|
||||
return symbolsByOffset.keySet();
|
||||
}
|
||||
|
||||
|
@ -101,7 +101,7 @@ public class SymbolGroup {
|
|||
* Returns the list of symbols in the order they were seen.
|
||||
* @return the list of symbols.
|
||||
*/
|
||||
public List<AbstractMsSymbol> getOrderedSymbols() {
|
||||
List<AbstractMsSymbol> getOrderedSymbols() {
|
||||
List<AbstractMsSymbol> symbols = new ArrayList<>();
|
||||
for (long offset : offsets) {
|
||||
symbols.add(symbolsByOffset.get(offset));
|
||||
|
@ -144,6 +144,10 @@ public class SymbolGroup {
|
|||
}
|
||||
|
||||
//==============================================================================================
|
||||
/**
|
||||
* Iterator for {@link SymbolGroup} that iterates through {@link AbstractMsSymbol
|
||||
* AbstractMsSymbols}
|
||||
*/
|
||||
class AbstractMsSymbolIterator implements Iterator<AbstractMsSymbol> {
|
||||
|
||||
private int currentIndex;
|
||||
|
@ -163,9 +167,10 @@ public class SymbolGroup {
|
|||
}
|
||||
|
||||
/**
|
||||
* Peeks at and returns the next symbol without incrementing to the next. If none are left, then throws NoSuchElementException and
|
||||
* reinitializes the state for a new iteration.
|
||||
* @see #initGet()
|
||||
* Peeks at and returns the next symbol without incrementing to the next. If none are
|
||||
* left, then throws NoSuchElementException and reinitializes the state for a new
|
||||
* iteration.
|
||||
* @see #initGet()
|
||||
* @return the next symbol
|
||||
* @throws NoSuchElementException if there are no more elements
|
||||
*/
|
||||
|
@ -192,12 +197,12 @@ public class SymbolGroup {
|
|||
|
||||
/**
|
||||
* Returns the next symbol. If none are left, then throws NoSuchElementException and
|
||||
* reinitializes the state for a new iteration.
|
||||
* @see #initGet()
|
||||
* reinitializes the state for a new iteration.
|
||||
* @see #initGet()
|
||||
* @return the next symbol
|
||||
* @throws NoSuchElementException if there are no more elements
|
||||
*/
|
||||
public long getCurrentOffset() {
|
||||
long getCurrentOffset() {
|
||||
return currentOffset;
|
||||
}
|
||||
|
||||
|
@ -205,7 +210,7 @@ public class SymbolGroup {
|
|||
* Initialized the mechanism for requesting the symbols in sequence.
|
||||
* @see #hasNext()
|
||||
*/
|
||||
public void initGet() {
|
||||
void initGet() {
|
||||
currentIndex = 0;
|
||||
}
|
||||
|
||||
|
@ -214,7 +219,7 @@ public class SymbolGroup {
|
|||
* @param offset the offset to which to initialize the mechanism.
|
||||
* @see #hasNext()
|
||||
*/
|
||||
public void initGetByOffset(long offset) {
|
||||
void initGetByOffset(long offset) {
|
||||
int index = indexByOffset.get(offset);
|
||||
if (index < 0) {
|
||||
index = 0;
|
||||
|
@ -228,7 +233,7 @@ public class SymbolGroup {
|
|||
* Returns the module number.
|
||||
* @return the module number.
|
||||
*/
|
||||
public int getModuleNumber() {
|
||||
int getModuleNumber() {
|
||||
return moduleNumber;
|
||||
}
|
||||
|
||||
|
|
|
@ -30,10 +30,15 @@ import ghidra.util.exception.CancelledException;
|
|||
/**
|
||||
* Applier for {@link TrampolineMsSymbol} symbols.
|
||||
*/
|
||||
public class TrampolineSymbolApplier extends AbstractMsSymbolApplier {
|
||||
public class TrampolineSymbolApplier extends MsSymbolApplier {
|
||||
|
||||
private TrampolineMsSymbol symbol;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param applicator the {@link PdbApplicator} for which we are working.
|
||||
* @param iter the Iterator containing the symbol sequence being processed
|
||||
*/
|
||||
public TrampolineSymbolApplier(PdbApplicator applicator, AbstractMsSymbolIterator iter) {
|
||||
super(applicator, iter);
|
||||
AbstractMsSymbol abstractSymbol = iter.next();
|
||||
|
@ -45,16 +50,16 @@ public class TrampolineSymbolApplier extends AbstractMsSymbolApplier {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void applyTo(AbstractMsSymbolApplier applyToApplier) {
|
||||
void applyTo(MsSymbolApplier applyToApplier) {
|
||||
// Do nothing.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply() throws CancelledException, PdbException {
|
||||
void apply() throws CancelledException, PdbException {
|
||||
// We know the size of this trampoline, so use it to restrict the disassembly.
|
||||
Address symbolAddress = applicator.reladdr(symbol);
|
||||
Address symbolAddress = applicator.getAddress(symbol);
|
||||
Address targetAddress =
|
||||
applicator.reladdr(symbol.getSegmentTarget(), symbol.getOffsetTarget());
|
||||
applicator.getAddress(symbol.getSegmentTarget(), symbol.getOffsetTarget());
|
||||
|
||||
Function target = createNewFunction(targetAddress, 1);
|
||||
Function thunk = createNewFunction(symbolAddress, symbol.getSizeOfThunk());
|
||||
|
|
|
@ -18,23 +18,29 @@ package ghidra.app.util.pdb.pdbapplicator;
|
|||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.*;
|
||||
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.*;
|
||||
|
||||
public class TypeApplierParser {
|
||||
/**
|
||||
* Pseudo-factory for creating the {@link MsTypeApplier} for the {@link AbstractMsType}
|
||||
* indicated by the AbstractMsType and also its {@link RecordNumber}. This class also performs
|
||||
* caching of the applier by its RecordNumber.
|
||||
*/
|
||||
public class TypeApplierFactory {
|
||||
|
||||
private PdbApplicator applicator;
|
||||
private Map<RecordNumber, AbstractMsTypeApplier> appliersByRecordNumber;
|
||||
private Map<RecordNumber, MsTypeApplier> appliersByRecordNumber;
|
||||
|
||||
TypeApplierParser(PdbApplicator applicator) {
|
||||
TypeApplierFactory(PdbApplicator applicator) {
|
||||
this.applicator = applicator;
|
||||
appliersByRecordNumber = new HashMap<>();
|
||||
}
|
||||
|
||||
//==============================================================================================
|
||||
AbstractMsTypeApplier getApplierSpec(RecordNumber recordNumber,
|
||||
Class<? extends AbstractMsTypeApplier> expected) throws PdbException {
|
||||
AbstractMsTypeApplier applier = getTypeApplier(recordNumber);
|
||||
MsTypeApplier getApplierSpec(RecordNumber recordNumber, Class<? extends MsTypeApplier> expected)
|
||||
throws PdbException {
|
||||
MsTypeApplier applier = getTypeApplier(recordNumber);
|
||||
if (!expected.isInstance(applier)) {
|
||||
throw new PdbException(applier.getClass().getSimpleName() + " seen where " +
|
||||
expected.getSimpleName() + " expected for record number " + recordNumber);
|
||||
|
@ -42,9 +48,9 @@ public class TypeApplierParser {
|
|||
return applier;
|
||||
}
|
||||
|
||||
AbstractMsTypeApplier getApplierOrNoTypeSpec(RecordNumber recordNumber,
|
||||
Class<? extends AbstractMsTypeApplier> expected) throws PdbException {
|
||||
AbstractMsTypeApplier applier = getTypeApplier(recordNumber);
|
||||
MsTypeApplier getApplierOrNoTypeSpec(RecordNumber recordNumber,
|
||||
Class<? extends MsTypeApplier> expected) throws PdbException {
|
||||
MsTypeApplier applier = getTypeApplier(recordNumber);
|
||||
if (!expected.isInstance(applier)) {
|
||||
if (!(applier instanceof PrimitiveTypeApplier &&
|
||||
((PrimitiveTypeApplier) applier).isNoType())) {
|
||||
|
@ -55,8 +61,8 @@ public class TypeApplierParser {
|
|||
return applier;
|
||||
}
|
||||
|
||||
AbstractMsTypeApplier getTypeApplier(RecordNumber recordNumber) {
|
||||
AbstractMsTypeApplier applier = appliersByRecordNumber.get(recordNumber);
|
||||
MsTypeApplier getTypeApplier(RecordNumber recordNumber) {
|
||||
MsTypeApplier applier = appliersByRecordNumber.get(recordNumber);
|
||||
if (applier == null) {
|
||||
applier = getTypeApplier(applicator.getPdb().getTypeRecord(recordNumber));
|
||||
appliersByRecordNumber.put(recordNumber, applier);
|
||||
|
@ -65,48 +71,49 @@ public class TypeApplierParser {
|
|||
}
|
||||
|
||||
//==============================================================================================
|
||||
AbstractMsTypeApplier getTypeApplier(AbstractMsType type) {
|
||||
MsTypeApplier getTypeApplier(AbstractMsType type) {
|
||||
if (type == null) {
|
||||
applicator.appendLogMsg("PDB Warning: No AbstractMsType for getTypeApplier");
|
||||
return null;
|
||||
}
|
||||
AbstractMsTypeApplier applier = null;
|
||||
MsTypeApplier applier = null;
|
||||
try {
|
||||
switch (type.getPdbId()) {
|
||||
case -1:
|
||||
applier = new PrimitiveTypeApplier(applicator, type);
|
||||
case -1: // must be careful, as we chose the -1 for PrimitiveMsType
|
||||
applier = new PrimitiveTypeApplier(applicator, (PrimitiveMsType) type);
|
||||
break;
|
||||
|
||||
// 0x0000 block
|
||||
case Modifier16MsType.PDB_ID:
|
||||
applier = new ModifierTypeApplier(applicator, type);
|
||||
applier = new ModifierTypeApplier(applicator, (Modifier16MsType) type);
|
||||
break;
|
||||
case Pointer16MsType.PDB_ID:
|
||||
applier = new PointerTypeApplier(applicator, type);
|
||||
applier = new PointerTypeApplier(applicator, (Pointer16MsType) type);
|
||||
break;
|
||||
case Array16MsType.PDB_ID:
|
||||
applier = new ArrayTypeApplier(applicator, type);
|
||||
applier = new ArrayTypeApplier(applicator, (Array16MsType) type);
|
||||
break;
|
||||
case Class16MsType.PDB_ID:
|
||||
applier = new CompositeTypeApplier(applicator, type);
|
||||
applier = new CompositeTypeApplier(applicator, (Class16MsType) type);
|
||||
break;
|
||||
case Structure16MsType.PDB_ID:
|
||||
applier = new CompositeTypeApplier(applicator, type);
|
||||
applier = new CompositeTypeApplier(applicator, (Structure16MsType) type);
|
||||
break;
|
||||
case Union16MsType.PDB_ID:
|
||||
applier = new CompositeTypeApplier(applicator, type);
|
||||
applier = new CompositeTypeApplier(applicator, (Union16MsType) type);
|
||||
break;
|
||||
case Enum16MsType.PDB_ID:
|
||||
applier = new EnumTypeApplier(applicator, type);
|
||||
applier = new EnumTypeApplier(applicator, (Enum16MsType) type);
|
||||
break;
|
||||
case Procedure16MsType.PDB_ID:
|
||||
applier = new ProcedureTypeApplier(applicator, type);
|
||||
applier = new ProcedureTypeApplier(applicator, (Procedure16MsType) type);
|
||||
break;
|
||||
case MemberFunction16MsType.PDB_ID:
|
||||
applier = new MemberFunctionTypeApplier(applicator, type);
|
||||
applier =
|
||||
new MemberFunctionTypeApplier(applicator, (MemberFunction16MsType) type);
|
||||
break;
|
||||
case VtShapeMsType.PDB_ID:
|
||||
applier = new VtShapeTypeApplier(applicator, type);
|
||||
applier = new VtShapeTypeApplier(applicator, (VtShapeMsType) type);
|
||||
break;
|
||||
// case Cobol016MsType.PDB_ID:
|
||||
// // Not evaluated/implemented yet.
|
||||
|
@ -150,7 +157,8 @@ public class TypeApplierParser {
|
|||
// // Not evaluated/implemented yet.
|
||||
// break;
|
||||
case ArgumentsList16MsType.PDB_ID:
|
||||
applier = new ArgumentsListTypeApplier(applicator, type);
|
||||
applier =
|
||||
new ArgumentsListTypeApplier(applicator, (ArgumentsList16MsType) type);
|
||||
break;
|
||||
// case DefaultArguments16MsType.PDB_ID:
|
||||
// // Not evaluated/implemented yet.
|
||||
|
@ -165,7 +173,7 @@ public class TypeApplierParser {
|
|||
// // Not evaluated/implemented yet.
|
||||
// break;
|
||||
case Bitfield16MsType.PDB_ID:
|
||||
applier = new BitfieldTypeApplier(applicator, type);
|
||||
applier = new BitfieldTypeApplier(applicator, (Bitfield16MsType) type);
|
||||
break;
|
||||
// case MethodList16MsType.PDB_ID:
|
||||
// // Not evaluated/implemented yet.
|
||||
|
@ -182,9 +190,9 @@ public class TypeApplierParser {
|
|||
// case DimensionedArrayVarBoundsLowerUpper16MsType.PDB_ID:
|
||||
// // Not evaluated/implemented yet.
|
||||
// break;
|
||||
case ReferencedSymbolMsType.PDB_ID:
|
||||
// Not evaluated/implemented yet.
|
||||
break;
|
||||
// case ReferencedSymbolMsType.PDB_ID:
|
||||
// // Not evaluated/implemented yet.
|
||||
// break;
|
||||
|
||||
// 0x400 block
|
||||
case BaseClass16MsType.PDB_ID:
|
||||
|
@ -197,7 +205,7 @@ public class TypeApplierParser {
|
|||
applier = new BaseClassTypeApplier(applicator, type);
|
||||
break;
|
||||
case EnumerateStMsType.PDB_ID:
|
||||
applier = new EnumerateTypeApplier(applicator, type);
|
||||
applier = new EnumerateTypeApplier(applicator, (EnumerateStMsType) type);
|
||||
break;
|
||||
// case FriendFunction16MsType.PDB_ID:
|
||||
// // Not evaluated/implemented yet.
|
||||
|
@ -206,7 +214,7 @@ public class TypeApplierParser {
|
|||
// // Not evaluated/implemented yet.
|
||||
// break;
|
||||
case Member16MsType.PDB_ID:
|
||||
applier = new MemberTypeApplier(applicator, type);
|
||||
applier = new MemberTypeApplier(applicator, (Member16MsType) type);
|
||||
break;
|
||||
// case StaticMember16MsType.PDB_ID:
|
||||
// // Not evaluated/implemented yet.
|
||||
|
@ -234,31 +242,32 @@ public class TypeApplierParser {
|
|||
|
||||
// 0x1000 block
|
||||
case ModifierMsType.PDB_ID:
|
||||
applier = new ModifierTypeApplier(applicator, type);
|
||||
applier = new ModifierTypeApplier(applicator, (ModifierMsType) type);
|
||||
break;
|
||||
case PointerMsType.PDB_ID:
|
||||
applier = new PointerTypeApplier(applicator, type);
|
||||
applier = new PointerTypeApplier(applicator, (PointerMsType) type);
|
||||
break;
|
||||
case ArrayStMsType.PDB_ID:
|
||||
applier = new ArrayTypeApplier(applicator, type);
|
||||
applier = new ArrayTypeApplier(applicator, (ArrayStMsType) type);
|
||||
break;
|
||||
case ClassStMsType.PDB_ID:
|
||||
applier = new CompositeTypeApplier(applicator, type);
|
||||
applier = new CompositeTypeApplier(applicator, (ClassStMsType) type);
|
||||
break;
|
||||
case StructureStMsType.PDB_ID:
|
||||
applier = new CompositeTypeApplier(applicator, type);
|
||||
applier = new CompositeTypeApplier(applicator, (StructureStMsType) type);
|
||||
break;
|
||||
case UnionStMsType.PDB_ID:
|
||||
applier = new CompositeTypeApplier(applicator, type);
|
||||
applier = new CompositeTypeApplier(applicator, (UnionStMsType) type);
|
||||
break;
|
||||
case EnumStMsType.PDB_ID:
|
||||
applier = new EnumTypeApplier(applicator, type);
|
||||
applier = new EnumTypeApplier(applicator, (EnumStMsType) type);
|
||||
break;
|
||||
case ProcedureMsType.PDB_ID:
|
||||
applier = new ProcedureTypeApplier(applicator, type);
|
||||
applier = new ProcedureTypeApplier(applicator, (ProcedureMsType) type);
|
||||
break;
|
||||
case MemberFunctionMsType.PDB_ID:
|
||||
applier = new MemberFunctionTypeApplier(applicator, type);
|
||||
applier =
|
||||
new MemberFunctionTypeApplier(applicator, (MemberFunctionMsType) type);
|
||||
break;
|
||||
// case Cobol0MsType.PDB_ID:
|
||||
// // Not evaluated/implemented yet.
|
||||
|
@ -290,7 +299,7 @@ public class TypeApplierParser {
|
|||
// // Not evaluated/implemented yet.
|
||||
// break;
|
||||
case ArgumentsListMsType.PDB_ID:
|
||||
applier = new ArgumentsListTypeApplier(applicator, type);
|
||||
applier = new ArgumentsListTypeApplier(applicator, (ArgumentsListMsType) type);
|
||||
break;
|
||||
// case DefaultArgumentsStMsType.PDB_ID:
|
||||
// // Not evaluated/implemented yet.
|
||||
|
@ -302,7 +311,7 @@ public class TypeApplierParser {
|
|||
// // Not evaluated/implemented yet.
|
||||
// break;
|
||||
case BitfieldMsType.PDB_ID:
|
||||
applier = new BitfieldTypeApplier(applicator, type);
|
||||
applier = new BitfieldTypeApplier(applicator, (BitfieldMsType) type);
|
||||
break;
|
||||
// case MethodListMsType.PDB_ID:
|
||||
// // Not evaluated/implemented yet.
|
||||
|
@ -337,7 +346,7 @@ public class TypeApplierParser {
|
|||
// // Not evaluated/implemented yet.
|
||||
// break;
|
||||
case MemberStMsType.PDB_ID:
|
||||
applier = new MemberTypeApplier(applicator, type);
|
||||
applier = new MemberTypeApplier(applicator, (MemberStMsType) type);
|
||||
break;
|
||||
// case StaticMemberStMsType.PDB_ID:
|
||||
// // Not evaluated/implemented yet.
|
||||
|
@ -377,22 +386,22 @@ public class TypeApplierParser {
|
|||
// // Not evaluated/implemented yet.
|
||||
// break;
|
||||
case EnumerateMsType.PDB_ID:
|
||||
applier = new EnumerateTypeApplier(applicator, type);
|
||||
applier = new EnumerateTypeApplier(applicator, (EnumerateMsType) type);
|
||||
break;
|
||||
case ArrayMsType.PDB_ID:
|
||||
applier = new ArrayTypeApplier(applicator, type);
|
||||
applier = new ArrayTypeApplier(applicator, (ArrayMsType) type);
|
||||
break;
|
||||
case ClassMsType.PDB_ID:
|
||||
applier = new CompositeTypeApplier(applicator, type);
|
||||
applier = new CompositeTypeApplier(applicator, (ClassMsType) type);
|
||||
break;
|
||||
case StructureMsType.PDB_ID:
|
||||
applier = new CompositeTypeApplier(applicator, type);
|
||||
applier = new CompositeTypeApplier(applicator, (StructureMsType) type);
|
||||
break;
|
||||
case UnionMsType.PDB_ID:
|
||||
applier = new CompositeTypeApplier(applicator, type);
|
||||
applier = new CompositeTypeApplier(applicator, (UnionMsType) type);
|
||||
break;
|
||||
case EnumMsType.PDB_ID:
|
||||
applier = new EnumTypeApplier(applicator, type);
|
||||
applier = new EnumTypeApplier(applicator, (EnumMsType) type);
|
||||
break;
|
||||
// case DimensionedArrayMsType.PDB_ID:
|
||||
// // Not evaluated/implemented yet.
|
||||
|
@ -410,7 +419,7 @@ public class TypeApplierParser {
|
|||
// // Not evaluated/implemented yet.
|
||||
// break;
|
||||
case MemberMsType.PDB_ID:
|
||||
applier = new MemberTypeApplier(applicator, type);
|
||||
applier = new MemberTypeApplier(applicator, (MemberMsType) type);
|
||||
break;
|
||||
// case StaticMemberMsType.PDB_ID:
|
||||
// // Not evaluated/implemented yet.
|
||||
|
@ -448,7 +457,7 @@ public class TypeApplierParser {
|
|||
// // Not evaluated/implemented yet.
|
||||
// break;
|
||||
case InterfaceMsType.PDB_ID:
|
||||
applier = new CompositeTypeApplier(applicator, type);
|
||||
applier = new CompositeTypeApplier(applicator, (InterfaceMsType) type);
|
||||
break;
|
||||
// case BaseInterfaceMsType.PDB_ID:
|
||||
// // Not evaluated/implemented yet.
|
||||
|
@ -511,7 +520,7 @@ public class TypeApplierParser {
|
|||
String message = "GhidraException on " + msg + " with PdbId " + type.getPdbId() + ": " +
|
||||
e.getMessage();
|
||||
applicator.appendLogMsg(message);
|
||||
PdbLog.message(message);
|
||||
applicator.pdbLogAndInfoMessage(this, message);
|
||||
}
|
||||
return applier;
|
||||
}
|
|
@ -28,11 +28,16 @@ import ghidra.util.exception.CancelledException;
|
|||
/**
|
||||
* Applier for {@link AbstractUserDefinedTypeMsSymbol} symbols.
|
||||
*/
|
||||
public class TypedefSymbolApplier extends AbstractMsSymbolApplier {
|
||||
public class TypedefSymbolApplier extends MsSymbolApplier {
|
||||
|
||||
DataType resolvedDataType = null;
|
||||
AbstractUserDefinedTypeMsSymbol udtSymbol;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param applicator the {@link PdbApplicator} for which we are working.
|
||||
* @param iter the Iterator containing the symbol sequence being processed
|
||||
*/
|
||||
public TypedefSymbolApplier(PdbApplicator applicator, AbstractMsSymbolIterator iter) {
|
||||
super(applicator, iter);
|
||||
AbstractMsSymbol abstractSymbol = iter.next();
|
||||
|
@ -44,12 +49,12 @@ public class TypedefSymbolApplier extends AbstractMsSymbolApplier {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void applyTo(AbstractMsSymbolApplier applyToApplier) {
|
||||
void applyTo(MsSymbolApplier applyToApplier) {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply() throws PdbException, CancelledException {
|
||||
void apply() throws PdbException, CancelledException {
|
||||
resolvedDataType = applyUserDefinedTypeMsSymbol(udtSymbol);
|
||||
}
|
||||
|
||||
|
@ -57,7 +62,7 @@ public class TypedefSymbolApplier extends AbstractMsSymbolApplier {
|
|||
* Returns the name.
|
||||
* @return Name.
|
||||
*/
|
||||
public String getName() {
|
||||
String getName() {
|
||||
return udtSymbol.getName();
|
||||
}
|
||||
|
||||
|
@ -65,11 +70,11 @@ public class TypedefSymbolApplier extends AbstractMsSymbolApplier {
|
|||
* Returns the type record number.
|
||||
* @return Type record number.
|
||||
*/
|
||||
public RecordNumber getTypeRecordNumber() {
|
||||
RecordNumber getTypeRecordNumber() {
|
||||
return udtSymbol.getTypeRecordNumber();
|
||||
}
|
||||
|
||||
public DataType getResolvedDataType() throws PdbException {
|
||||
DataType getResolvedDataType() throws PdbException {
|
||||
if (resolvedDataType == null) {
|
||||
throw new PdbException("Data type not resolved");
|
||||
}
|
||||
|
@ -81,7 +86,7 @@ public class TypedefSymbolApplier extends AbstractMsSymbolApplier {
|
|||
|
||||
String name = symbol.getName();
|
||||
|
||||
AbstractMsTypeApplier applier = applicator.getTypeApplier(symbol.getTypeRecordNumber());
|
||||
MsTypeApplier applier = applicator.getTypeApplier(symbol.getTypeRecordNumber());
|
||||
// TODO:... NOT SURE IF WILL ALWAYS BE A DATATYPE OR WILL BE A VARIABLE OR ????
|
||||
if (applier == null) {
|
||||
return null;
|
||||
|
|
|
@ -24,9 +24,9 @@ import ghidra.util.exception.CancelledException;
|
|||
|
||||
/**
|
||||
* Applier for {@link AbstractBaseClassMsType}, {@link AbstractVirtualBaseClassMsType}, and
|
||||
* {@link AbstractIndirectVirtualBaseClassMsType} types.
|
||||
* {@link AbstractIndirectVirtualBaseClassMsType} types.
|
||||
*/
|
||||
public class UdtSourceLineTypeApplier extends AbstractMsTypeApplier {
|
||||
public class UdtSourceLineTypeApplier extends MsTypeApplier {
|
||||
|
||||
private static AbstractMsType validateType(AbstractMsType type)
|
||||
throws IllegalArgumentException {
|
||||
|
@ -56,7 +56,7 @@ public class UdtSourceLineTypeApplier extends AbstractMsTypeApplier {
|
|||
// For here, we are only reporting what "we" have, not what the underlying sizes are.
|
||||
// ...and a value of zero is our "don't know" and "not represented" value.
|
||||
@Override
|
||||
public BigInteger getSize() {
|
||||
BigInteger getSize() {
|
||||
return BigInteger.ZERO;
|
||||
}
|
||||
|
||||
|
@ -64,7 +64,7 @@ public class UdtSourceLineTypeApplier extends AbstractMsTypeApplier {
|
|||
* Returns the offset of the Base Class within the inheriting class.
|
||||
* @return the offset.
|
||||
*/
|
||||
public int getLineNumber() {
|
||||
int getLineNumber() {
|
||||
if (msType instanceof UserDefinedTypeSourceAndLineMsType) {
|
||||
return ((UserDefinedTypeSourceAndLineMsType) msType).getLineNumber();
|
||||
}
|
||||
|
@ -75,7 +75,7 @@ public class UdtSourceLineTypeApplier extends AbstractMsTypeApplier {
|
|||
* Returns the source file name.
|
||||
* @return the source file name. null if problem recovering name.
|
||||
*/
|
||||
public String getSourceFileName() {
|
||||
String getSourceFileName() {
|
||||
if (msType instanceof UserDefinedTypeSourceAndLineMsType) {
|
||||
return ((UserDefinedTypeSourceAndLineMsType) msType).getSourceFileName();
|
||||
}
|
||||
|
@ -86,7 +86,7 @@ public class UdtSourceLineTypeApplier extends AbstractMsTypeApplier {
|
|||
* Returns the record number of the UDT.
|
||||
* @return the record number of the UDT.
|
||||
*/
|
||||
public RecordNumber getUdtRecordNumber() {
|
||||
RecordNumber getUdtRecordNumber() {
|
||||
if (msType instanceof UserDefinedTypeSourceAndLineMsType) {
|
||||
return ((UserDefinedTypeSourceAndLineMsType) msType).getUdtRecordNumber();
|
||||
}
|
||||
|
@ -94,11 +94,11 @@ public class UdtSourceLineTypeApplier extends AbstractMsTypeApplier {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void apply() throws PdbException, CancelledException {
|
||||
void apply() throws PdbException, CancelledException {
|
||||
String filename = getSourceFileName();
|
||||
int lineNumber = getLineNumber();
|
||||
RecordNumber udtRecordNumber = getUdtRecordNumber();
|
||||
AbstractMsTypeApplier typeApplier = applicator.getTypeApplier(udtRecordNumber);
|
||||
MsTypeApplier typeApplier = applicator.getTypeApplier(udtRecordNumber);
|
||||
|
||||
// do nothing at the moment.
|
||||
applicator.putRecordNumberByFileName(udtRecordNumber, filename);
|
||||
|
|
|
@ -25,9 +25,9 @@ import ghidra.util.exception.CancelledException;
|
|||
|
||||
/**
|
||||
* Applier for {@link AbstractVirtualFunctionTablePointerMsType} and
|
||||
* {@link AbstractVirtualFunctionTablePointerWithOffsetMsType} types.
|
||||
* {@link AbstractVirtualFunctionTablePointerWithOffsetMsType} types.
|
||||
*/
|
||||
public class VirtualFunctionTablePointerTypeApplier extends AbstractMsTypeApplier {
|
||||
public class VirtualFunctionTablePointerTypeApplier extends MsTypeApplier {
|
||||
|
||||
DataType vtShape = null;
|
||||
|
||||
|
@ -44,18 +44,19 @@ public class VirtualFunctionTablePointerTypeApplier extends AbstractMsTypeApplie
|
|||
|
||||
/**
|
||||
* Constructor for enum type applier, for transforming a enum into a
|
||||
* Ghidra DataType.
|
||||
* Ghidra DataType.
|
||||
* @param applicator {@link PdbApplicator} for which this class is working.
|
||||
* @param msType {@link AbstractVirtualFunctionTablePointerMsType} or
|
||||
* {@link AbstractVirtualFunctionTablePointerWithOffsetMsType} to process.
|
||||
* @throws IllegalArgumentException Upon invalid arguments.
|
||||
*/
|
||||
public VirtualFunctionTablePointerTypeApplier(PdbApplicator applicator, AbstractMsType msType) throws IllegalArgumentException {
|
||||
public VirtualFunctionTablePointerTypeApplier(PdbApplicator applicator, AbstractMsType msType)
|
||||
throws IllegalArgumentException {
|
||||
super(applicator, validateType(msType));
|
||||
}
|
||||
|
||||
@Override
|
||||
public BigInteger getSize() {
|
||||
BigInteger getSize() {
|
||||
return BigInteger.valueOf(applicator.getDataOrganization().getPointerSize());
|
||||
}
|
||||
|
||||
|
@ -63,7 +64,7 @@ public class VirtualFunctionTablePointerTypeApplier extends AbstractMsTypeApplie
|
|||
* Returns the offset of the Virtual Function Table Pointer.
|
||||
* @return Name of the nested type.
|
||||
*/
|
||||
public int getOffset() {
|
||||
int getOffset() {
|
||||
if (msType instanceof AbstractVirtualFunctionTablePointerWithOffsetMsType) {
|
||||
return ((AbstractVirtualFunctionTablePointerWithOffsetMsType) msType).getOffset();
|
||||
}
|
||||
|
@ -74,12 +75,12 @@ public class VirtualFunctionTablePointerTypeApplier extends AbstractMsTypeApplie
|
|||
* Returns the name to use.
|
||||
* @return Name of the pointer type.
|
||||
*/
|
||||
public String getMemberName() {
|
||||
String getMemberName() {
|
||||
return "VFTablePtr" + getOffset();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply() throws PdbException, CancelledException {
|
||||
void apply() throws PdbException, CancelledException {
|
||||
if (msType instanceof AbstractVirtualFunctionTablePointerMsType) {
|
||||
dataType = applyPointer(
|
||||
((AbstractVirtualFunctionTablePointerMsType) msType).getPointerTypeRecordNumber());
|
||||
|
@ -90,9 +91,8 @@ public class VirtualFunctionTablePointerTypeApplier extends AbstractMsTypeApplie
|
|||
}
|
||||
}
|
||||
|
||||
// private DataType applyPointer(int pointerTypeIndex) throws PdbException {
|
||||
private DataType applyPointer(RecordNumber pointerTypeRecordNumber) {
|
||||
AbstractMsTypeApplier rawApplier = applicator.getTypeApplier(pointerTypeRecordNumber);
|
||||
MsTypeApplier rawApplier = applicator.getTypeApplier(pointerTypeRecordNumber);
|
||||
if (rawApplier instanceof PointerTypeApplier) {
|
||||
return rawApplier.getDataType();
|
||||
}
|
||||
|
|
|
@ -21,7 +21,8 @@ import java.util.List;
|
|||
|
||||
import ghidra.app.util.bin.format.pdb.DefaultCompositeMember;
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.PdbException;
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.type.*;
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.type.VtShapeDescriptorMsProperty;
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.type.VtShapeMsType;
|
||||
import ghidra.program.model.data.*;
|
||||
import ghidra.util.Msg;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
|
@ -29,31 +30,19 @@ import ghidra.util.exception.CancelledException;
|
|||
/**
|
||||
* Applier for {@link VtShapeMsType} types.
|
||||
*/
|
||||
public class VtShapeTypeApplier extends AbstractMsTypeApplier {
|
||||
|
||||
private static AbstractMsType validateType(AbstractMsType type)
|
||||
throws IllegalArgumentException {
|
||||
if (!(type instanceof VtShapeMsType)) {
|
||||
throw new IllegalArgumentException(
|
||||
"PDB Incorrectly applying " + type.getClass().getSimpleName() + " to " +
|
||||
VtShapeTypeApplier.class.getSimpleName());
|
||||
}
|
||||
return type;
|
||||
}
|
||||
public class VtShapeTypeApplier extends MsTypeApplier {
|
||||
|
||||
/**
|
||||
* Constructor for vtshape type applier.
|
||||
* @param applicator {@link PdbApplicator} for which this class is working.
|
||||
* @param msType {@link VtShapeMsType} to process.
|
||||
* @throws IllegalArgumentException Upon invalid arguments.
|
||||
*/
|
||||
public VtShapeTypeApplier(PdbApplicator applicator, AbstractMsType msType)
|
||||
throws IllegalArgumentException {
|
||||
super(applicator, validateType(msType));
|
||||
public VtShapeTypeApplier(PdbApplicator applicator, VtShapeMsType msType) {
|
||||
super(applicator, msType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BigInteger getSize() {
|
||||
BigInteger getSize() {
|
||||
return BigInteger.valueOf(applicator.getDataOrganization().getPointerSize() *
|
||||
((VtShapeMsType) msType).getCount());
|
||||
}
|
||||
|
@ -62,12 +51,12 @@ public class VtShapeTypeApplier extends AbstractMsTypeApplier {
|
|||
* Returns the name.
|
||||
* @return the name.
|
||||
*/
|
||||
public String getName() {
|
||||
String getName() {
|
||||
return "vtshape_" + index;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply() throws PdbException, CancelledException {
|
||||
void apply() throws PdbException, CancelledException {
|
||||
dataType = createVtShape((VtShapeMsType) msType);
|
||||
}
|
||||
|
||||
|
@ -78,7 +67,7 @@ public class VtShapeTypeApplier extends AbstractMsTypeApplier {
|
|||
// TODO: what are correct/appropriate CategoryPath and name
|
||||
StructureDataType shape = new StructureDataType(applicator.getAnonymousTypesCategory(),
|
||||
"vtshape" + index, 0, applicator.getDataTypeManager());
|
||||
List<Default2PdbMember> members = new ArrayList<>();
|
||||
List<DefaultPdbUniversalMember> members = new ArrayList<>();
|
||||
int offset = 0;
|
||||
for (VtShapeDescriptorMsProperty descriptor : list) {
|
||||
switch (descriptor) {
|
||||
|
@ -90,8 +79,8 @@ public class VtShapeTypeApplier extends AbstractMsTypeApplier {
|
|||
case NEAR32:
|
||||
case FAR32:
|
||||
Pointer pointer = new PointerDataType(applicator.getDataTypeManager());
|
||||
Default2PdbMember member =
|
||||
new Default2PdbMember(applicator, "", pointer, offset);
|
||||
DefaultPdbUniversalMember member =
|
||||
new DefaultPdbUniversalMember(applicator, "", pointer, offset);
|
||||
offset += pointer.getLength();
|
||||
members.add(member);
|
||||
break;
|
||||
|
|
|
@ -16,24 +16,27 @@
|
|||
package ghidra.app.util.pdb.pdbapplicator;
|
||||
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.PdbException;
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.PdbLog;
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.symbol.AbstractMsSymbol;
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.symbol.AbstractWithMsSymbol;
|
||||
import ghidra.app.util.pdb.pdbapplicator.SymbolGroup.AbstractMsSymbolIterator;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.util.Msg;
|
||||
import ghidra.util.exception.AssertException;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
|
||||
/**
|
||||
* Applier for {@link AbstractWithMsSymbol} symbols. This is not fully implemented
|
||||
* because we do not know its usage or have examples, but we have implemented
|
||||
* the block management portion.
|
||||
* because we do not know its usage or have examples, but we have implemented
|
||||
* the block management portion.
|
||||
*/
|
||||
public class WithSymbolApplier extends AbstractMsSymbolApplier {
|
||||
public class WithSymbolApplier extends MsSymbolApplier {
|
||||
|
||||
private AbstractWithMsSymbol symbol;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param applicator the {@link PdbApplicator} for which we are working.
|
||||
* @param iter the Iterator containing the symbol sequence being processed
|
||||
*/
|
||||
public WithSymbolApplier(PdbApplicator applicator, AbstractMsSymbolIterator iter) {
|
||||
super(applicator, iter);
|
||||
AbstractMsSymbol abstractSymbol = iter.next();
|
||||
|
@ -45,23 +48,22 @@ public class WithSymbolApplier extends AbstractMsSymbolApplier {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void apply() throws PdbException, CancelledException {
|
||||
void apply() throws PdbException, CancelledException {
|
||||
// TODO: We do not know if this can be applied to a program or not. We have no examples.
|
||||
String message = "Cannot apply " + this.getClass().getSimpleName() + " directly to program";
|
||||
Msg.info(this, message);
|
||||
PdbLog.message(message);
|
||||
pdbLogAndInfoMessage(this,
|
||||
"Cannot apply " + this.getClass().getSimpleName() + " directly to program");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyTo(AbstractMsSymbolApplier applyToApplier) {
|
||||
void applyTo(MsSymbolApplier applyToApplier) {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void manageBlockNesting(AbstractMsSymbolApplier applierParam) {
|
||||
void manageBlockNesting(MsSymbolApplier applierParam) {
|
||||
if (applierParam instanceof FunctionSymbolApplier) {
|
||||
FunctionSymbolApplier functionSymbolApplier = (FunctionSymbolApplier) applierParam;
|
||||
Address address = applicator.reladdr(symbol);
|
||||
Address address = applicator.getAddress(symbol);
|
||||
// TODO: not sure if getExpression() is correct, but there is no "name."
|
||||
functionSymbolApplier.beginBlock(address, symbol.getExpression(), symbol.getLength());
|
||||
}
|
||||
|
|
|
@ -52,8 +52,7 @@ public class CppCompositeTypeTest extends AbstractGenericTest {
|
|||
private static VbtManager vbtManager32;
|
||||
private static VbtManager vbtManager64;
|
||||
// Note: Currently all test have expected results based on up the COMPLEX layout.
|
||||
private static CompositeLayoutMode layoutOptions =
|
||||
CompositeLayoutMode.COMPLEX;
|
||||
private static CompositeLayoutMode layoutOptions = CompositeLayoutMode.COMPLEX;
|
||||
|
||||
static {
|
||||
BitFieldPackingImpl bitFieldPacking = new BitFieldPackingImpl();
|
||||
|
@ -277,6 +276,7 @@ public class CppCompositeTypeTest extends AbstractGenericTest {
|
|||
preparer32.addIntegers(new int[] { 0, 12 });
|
||||
preparer64.addIntegers(new int[] { 0, 20 });
|
||||
|
||||
// TODO: do not delete... these are for future use.
|
||||
// vbtSymbols.add("??_8GX1@@7B@");
|
||||
// preparer32.addIntegers(new int[] { 0, 4 });
|
||||
// preparer64.addIntegers(new int[] { 0, 8});
|
||||
|
@ -500,8 +500,9 @@ public class CppCompositeTypeTest extends AbstractGenericTest {
|
|||
builder.append('V');
|
||||
break;
|
||||
default:
|
||||
Msg.error(null, "Cannot handle type during testing" + type);
|
||||
assert false;
|
||||
String msg = "Cannot handle type during testing" + type;
|
||||
Msg.error(null, msg);
|
||||
throw new AssertException(msg);
|
||||
}
|
||||
builder.append(className);
|
||||
builder.append("@@");
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue