GT-3112 - PDB Universal - review changes

This commit is contained in:
ghizard 2020-09-06 18:00:59 -04:00
parent a1d7ed2cb2
commit 9f7fc60f76
65 changed files with 1046 additions and 1045 deletions

View file

@ -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

View file

@ -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);

View file

@ -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);

View file

@ -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;

View file

@ -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;
}

View file

@ -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()) {

View file

@ -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();
}

View file

@ -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.
}

View file

@ -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!!!
}

View file

@ -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 = " ";

View file

@ -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());
}
}

View file

@ -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();

View file

@ -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;
}
}

View file

@ -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;

View file

@ -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.

View file

@ -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());
}

View file

@ -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;
}

View file

@ -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 =

View file

@ -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();

View file

@ -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();

View file

@ -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;
}

View file

@ -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

View file

@ -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
}
}

View file

@ -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;
}

View file

@ -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
}
}

View file

@ -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;
}

View file

@ -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();
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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.
}

View file

@ -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);
}

View file

@ -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;
}
}

View file

@ -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.
}

View file

@ -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("");
}

View file

@ -15,8 +15,9 @@
*/
package ghidra.app.util.pdb.pdbapplicator;
//----------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------
/**
* Mode for {@link CppCompositeType} class layout.
*/
enum OoComponentLayoutMode {
UNKNOWN, MEMBERS_ONLY, BASIC, SIMPLE, COMPLEX
}

View file

@ -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();

View file

@ -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());
}

View file

@ -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());

View file

@ -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) {

View file

@ -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 {

View file

@ -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;

View file

@ -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);

View file

@ -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);
}
}

View file

@ -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
}

View file

@ -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
}
}

View file

@ -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) {

View file

@ -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);
}

View file

@ -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;

View file

@ -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());
}
}

View file

@ -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);

View file

@ -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;

View file

@ -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);
}

View file

@ -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

View file

@ -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;
}

View file

@ -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());

View file

@ -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;
}

View file

@ -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;

View file

@ -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);

View file

@ -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();
}

View file

@ -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;

View file

@ -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());
}

View file

@ -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("@@");