mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 10:49:34 +02:00
GP-4595 - PDB fix class containing member with same type name and primitive typedef and use default type handler
This commit is contained in:
parent
2b73a6157f
commit
3326d42baf
7 changed files with 116 additions and 73 deletions
|
@ -198,7 +198,7 @@ public class Pagedump extends DumpFile {
|
||||||
pdb.deserialize();
|
pdb.deserialize();
|
||||||
DefaultPdbApplicator applicator =
|
DefaultPdbApplicator applicator =
|
||||||
new DefaultPdbApplicator(pdb, program, program.getDataTypeManager(),
|
new DefaultPdbApplicator(pdb, program, program.getDataTypeManager(),
|
||||||
program.getImageBase(), applicatorOptions, (MessageLog) null);
|
program.getImageBase(), applicatorOptions, monitor, (MessageLog) null);
|
||||||
applicator.applyNoAnalysisState();
|
applicator.applyNoAnalysisState();
|
||||||
}
|
}
|
||||||
catch (PdbException | IOException | CancelledException e) {
|
catch (PdbException | IOException | CancelledException e) {
|
||||||
|
|
|
@ -110,8 +110,9 @@ public class PdbDeveloperApplyDummyScript extends GhidraScript {
|
||||||
try (AbstractPdb pdb = PdbParser.parse(pdbFile, pdbReaderOptions, monitor)) {
|
try (AbstractPdb pdb = PdbParser.parse(pdbFile, pdbReaderOptions, monitor)) {
|
||||||
monitor.setMessage("PDB: Parsing " + pdbFile + "...");
|
monitor.setMessage("PDB: Parsing " + pdbFile + "...");
|
||||||
pdb.deserialize();
|
pdb.deserialize();
|
||||||
DefaultPdbApplicator applicator = new DefaultPdbApplicator(pdb, program,
|
DefaultPdbApplicator applicator =
|
||||||
program.getDataTypeManager(), program.getImageBase(), pdbApplicatorOptions, log);
|
new DefaultPdbApplicator(pdb, program, program.getDataTypeManager(),
|
||||||
|
program.getImageBase(), pdbApplicatorOptions, monitor, log);
|
||||||
applicator.applyNoAnalysisState();
|
applicator.applyNoAnalysisState();
|
||||||
}
|
}
|
||||||
catch (PdbException | IOException e) {
|
catch (PdbException | IOException e) {
|
||||||
|
|
|
@ -205,8 +205,9 @@ public class PdbUniversalAnalyzer extends AbstractAnalyzer {
|
||||||
monitor.setMessage("PDB: Parsing " + pdbFile + "...");
|
monitor.setMessage("PDB: Parsing " + pdbFile + "...");
|
||||||
pdb.deserialize();
|
pdb.deserialize();
|
||||||
|
|
||||||
DefaultPdbApplicator applicator = new DefaultPdbApplicator(pdb, program,
|
DefaultPdbApplicator applicator =
|
||||||
program.getDataTypeManager(), program.getImageBase(), pdbApplicatorOptions, log);
|
new DefaultPdbApplicator(pdb, program, program.getDataTypeManager(),
|
||||||
|
program.getImageBase(), pdbApplicatorOptions, monitor, log);
|
||||||
applicator.applyDataTypesAndMainSymbolsAnalysis();
|
applicator.applyDataTypesAndMainSymbolsAnalysis();
|
||||||
|
|
||||||
AutoAnalysisManager aam = AutoAnalysisManager.getAnalysisManager(program);
|
AutoAnalysisManager aam = AutoAnalysisManager.getAnalysisManager(program);
|
||||||
|
@ -360,7 +361,7 @@ public class PdbUniversalAnalyzer extends AbstractAnalyzer {
|
||||||
pdb.deserialize();
|
pdb.deserialize();
|
||||||
DefaultPdbApplicator applicator =
|
DefaultPdbApplicator applicator =
|
||||||
new DefaultPdbApplicator(pdb, program, program.getDataTypeManager(),
|
new DefaultPdbApplicator(pdb, program, program.getDataTypeManager(),
|
||||||
program.getImageBase(), pdbApplicatorOptions, log);
|
program.getImageBase(), pdbApplicatorOptions, monitor, log);
|
||||||
applicator.applyFunctionInternalsAnalysis();
|
applicator.applyFunctionInternalsAnalysis();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,9 @@ import ghidra.app.util.SymbolPathParser;
|
||||||
import ghidra.app.util.bin.format.pdb2.pdbreader.RecordNumber;
|
import ghidra.app.util.bin.format.pdb2.pdbreader.RecordNumber;
|
||||||
import ghidra.app.util.bin.format.pdb2.pdbreader.type.AbstractComplexMsType;
|
import ghidra.app.util.bin.format.pdb2.pdbreader.type.AbstractComplexMsType;
|
||||||
import ghidra.app.util.pdb.PdbNamespaceUtils;
|
import ghidra.app.util.pdb.PdbNamespaceUtils;
|
||||||
|
import ghidra.util.Msg;
|
||||||
|
import mdemangler.*;
|
||||||
|
import mdemangler.datatype.MDDataType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Applier for {@link AbstractComplexMsType} types.
|
* Applier for {@link AbstractComplexMsType} types.
|
||||||
|
@ -42,8 +45,21 @@ public abstract class AbstractComplexTypeApplier extends MsDataTypeApplier {
|
||||||
* @see #getFixedSymbolPath(AbstractComplexMsType type)
|
* @see #getFixedSymbolPath(AbstractComplexMsType type)
|
||||||
*/
|
*/
|
||||||
SymbolPath getSymbolPath(AbstractComplexMsType type) {
|
SymbolPath getSymbolPath(AbstractComplexMsType type) {
|
||||||
|
SymbolPath symbolPath = null;
|
||||||
|
// We added logic to check the mangled name first because we found some LLVM "lambda"
|
||||||
|
// symbols where the regular name was a generic "<lambda_0>" with a namespace, but this
|
||||||
|
// often had a member that also lambda that was marked with the exact same namespace/name
|
||||||
|
// as the containing structure. We found that the mangled names had more accurate and
|
||||||
|
// distinguished lambda numbers.
|
||||||
|
String mangledName = type.getMangledName();
|
||||||
|
if (mangledName != null) {
|
||||||
|
symbolPath = getSymbolPathFromMangledTypeName(mangledName);
|
||||||
|
}
|
||||||
|
if (symbolPath == null) {
|
||||||
String fullPathName = type.getName();
|
String fullPathName = type.getName();
|
||||||
return new SymbolPath(SymbolPathParser.parse(fullPathName));
|
symbolPath = new SymbolPath(SymbolPathParser.parse(fullPathName));
|
||||||
|
}
|
||||||
|
return symbolPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -75,4 +91,28 @@ public abstract class AbstractComplexTypeApplier extends MsDataTypeApplier {
|
||||||
return PdbNamespaceUtils.convertToGhidraPathName(path, num);
|
return PdbNamespaceUtils.convertToGhidraPathName(path, num);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private SymbolPath getSymbolPathFromMangledTypeName(String mangledString) {
|
||||||
|
MDMang demangler = new MDMangGhidra();
|
||||||
|
try {
|
||||||
|
MDDataType mdDataType = demangler.demangleType(mangledString, true);
|
||||||
|
// 20240626: Ultimately, it might be better to retrieve the Demangled-type to pass
|
||||||
|
// to the DemangledObject.createNamespace() method to convert to a true Ghidra
|
||||||
|
// Namespace that are flagged as functions (not capable at this time) or types or
|
||||||
|
// raw namespace nodes. Note, however, that the Demangler is still weak in this
|
||||||
|
// area as there are codes that we still not know how to interpret.
|
||||||
|
return MDMangUtils.getSymbolPath(mdDataType);
|
||||||
|
// Could consider the following simplification method instead
|
||||||
|
// return MDMangUtils.getSimpleSymbolPath(mdDataType);
|
||||||
|
}
|
||||||
|
catch (MDException e) {
|
||||||
|
// Couldn't demangle.
|
||||||
|
// Message might cause too much noise (we have a fallback, above, to use the regular
|
||||||
|
// name, but this could cause an error... see the notes above about why a mangled
|
||||||
|
// name is checked first).
|
||||||
|
Msg.info(this,
|
||||||
|
"PDB issue dmangling type name: " + e.getMessage() + " for : " + mangledString);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -136,8 +136,7 @@ public class CompositeTypeApplier extends AbstractComplexTypeApplier {
|
||||||
|
|
||||||
//==============================================================================================
|
//==============================================================================================
|
||||||
private void applyBasic(ComboType combo, AbstractCompositeMsType type,
|
private void applyBasic(ComboType combo, AbstractCompositeMsType type,
|
||||||
FieldListTypeApplier.FieldLists lists)
|
FieldListTypeApplier.FieldLists lists) throws CancelledException, PdbException {
|
||||||
throws CancelledException, PdbException {
|
|
||||||
Composite composite = combo.dt();
|
Composite composite = combo.dt();
|
||||||
CppCompositeType classType = combo.ct();
|
CppCompositeType classType = combo.ct();
|
||||||
boolean isClass = (type instanceof AbstractClassMsType);
|
boolean isClass = (type instanceof AbstractClassMsType);
|
||||||
|
@ -156,8 +155,7 @@ public class CompositeTypeApplier extends AbstractComplexTypeApplier {
|
||||||
|
|
||||||
//==============================================================================================
|
//==============================================================================================
|
||||||
private void applyCpp(ComboType combo, AbstractCompositeMsType type,
|
private void applyCpp(ComboType combo, AbstractCompositeMsType type,
|
||||||
FieldListTypeApplier.FieldLists lists)
|
FieldListTypeApplier.FieldLists lists) throws PdbException, CancelledException {
|
||||||
throws PdbException, CancelledException {
|
|
||||||
Composite composite = combo.dt();
|
Composite composite = combo.dt();
|
||||||
CppCompositeType classType = combo.ct();
|
CppCompositeType classType = combo.ct();
|
||||||
clearComponents(composite);
|
clearComponents(composite);
|
||||||
|
@ -243,8 +241,7 @@ public class CompositeTypeApplier extends AbstractComplexTypeApplier {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void applyDirectBaseClass(AbstractBaseClassMsType base, CppCompositeType myClassType,
|
private void applyDirectBaseClass(AbstractBaseClassMsType base, CppCompositeType myClassType,
|
||||||
Access defaultAccess)
|
Access defaultAccess) throws PdbException {
|
||||||
throws PdbException {
|
|
||||||
CppCompositeType underlyingClassType =
|
CppCompositeType underlyingClassType =
|
||||||
getUnderlyingClassType(base.getBaseClassRecordNumber());
|
getUnderlyingClassType(base.getBaseClassRecordNumber());
|
||||||
if (underlyingClassType == null) {
|
if (underlyingClassType == null) {
|
||||||
|
@ -258,25 +255,23 @@ public class CompositeTypeApplier extends AbstractComplexTypeApplier {
|
||||||
|
|
||||||
private void applyDirectVirtualBaseClass(AbstractVirtualBaseClassMsType base,
|
private void applyDirectVirtualBaseClass(AbstractVirtualBaseClassMsType base,
|
||||||
CppCompositeType myClassType, Access defaultAccess) throws PdbException {
|
CppCompositeType myClassType, Access defaultAccess) throws PdbException {
|
||||||
CppCompositeType underlyingCt =
|
CppCompositeType underlyingCt = getUnderlyingClassType(base.getBaseClassRecordNumber());
|
||||||
getUnderlyingClassType(base.getBaseClassRecordNumber());
|
|
||||||
if (underlyingCt == null) {
|
if (underlyingCt == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
DataType vbtptr = getVirtualBaseTablePointerDataType(
|
DataType vbtptr =
|
||||||
base.getVirtualBasePointerRecordNumber());
|
getVirtualBaseTablePointerDataType(base.getVirtualBasePointerRecordNumber());
|
||||||
ClassFieldMsAttributes atts = base.getAttributes();
|
ClassFieldMsAttributes atts = base.getAttributes();
|
||||||
int basePointerOffset = applicator.bigIntegerToInt(base.getBasePointerOffset());
|
int basePointerOffset = applicator.bigIntegerToInt(base.getBasePointerOffset());
|
||||||
int offsetFromVbt = applicator.bigIntegerToInt(base.getBaseOffsetFromVbt());
|
int offsetFromVbt = applicator.bigIntegerToInt(base.getBaseOffsetFromVbt());
|
||||||
myClassType.addDirectVirtualBaseClass(underlyingCt,
|
myClassType.addDirectVirtualBaseClass(underlyingCt,
|
||||||
ClassFieldAttributes.convert(atts, defaultAccess),
|
ClassFieldAttributes.convert(atts, defaultAccess), basePointerOffset, vbtptr,
|
||||||
basePointerOffset, vbtptr, offsetFromVbt);
|
offsetFromVbt);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void applyIndirectVirtualBaseClass(AbstractIndirectVirtualBaseClassMsType base,
|
private void applyIndirectVirtualBaseClass(AbstractIndirectVirtualBaseClassMsType base,
|
||||||
CppCompositeType myClassType, Access defaultAccess) throws PdbException {
|
CppCompositeType myClassType, Access defaultAccess) throws PdbException {
|
||||||
CppCompositeType underlyingCt =
|
CppCompositeType underlyingCt = getUnderlyingClassType(base.getBaseClassRecordNumber());
|
||||||
getUnderlyingClassType(base.getBaseClassRecordNumber());
|
|
||||||
if (underlyingCt == null) {
|
if (underlyingCt == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -286,8 +281,8 @@ public class CompositeTypeApplier extends AbstractComplexTypeApplier {
|
||||||
int basePointerOffset = applicator.bigIntegerToInt(base.getBasePointerOffset());
|
int basePointerOffset = applicator.bigIntegerToInt(base.getBasePointerOffset());
|
||||||
int offsetFromVbt = applicator.bigIntegerToInt(base.getBaseOffsetFromVbt());
|
int offsetFromVbt = applicator.bigIntegerToInt(base.getBaseOffsetFromVbt());
|
||||||
myClassType.addIndirectVirtualBaseClass(underlyingCt,
|
myClassType.addIndirectVirtualBaseClass(underlyingCt,
|
||||||
ClassFieldAttributes.convert(atts, defaultAccess),
|
ClassFieldAttributes.convert(atts, defaultAccess), basePointerOffset, vbtptr,
|
||||||
basePointerOffset, vbtptr, offsetFromVbt);
|
offsetFromVbt);
|
||||||
}
|
}
|
||||||
|
|
||||||
private CppCompositeType getUnderlyingClassType(RecordNumber recordNumber) {
|
private CppCompositeType getUnderlyingClassType(RecordNumber recordNumber) {
|
||||||
|
@ -324,8 +319,7 @@ public class CompositeTypeApplier extends AbstractComplexTypeApplier {
|
||||||
|
|
||||||
private void addMembers(Composite composite, CppCompositeType myClassType,
|
private void addMembers(Composite composite, CppCompositeType myClassType,
|
||||||
List<AbstractMemberMsType> msMembers, AbstractCompositeMsType type,
|
List<AbstractMemberMsType> msMembers, AbstractCompositeMsType type,
|
||||||
List<DefaultPdbUniversalMember> myMembers)
|
List<DefaultPdbUniversalMember> myMembers) throws CancelledException, PdbException {
|
||||||
throws CancelledException, PdbException {
|
|
||||||
ClassFieldAttributes.Access defaultAccess =
|
ClassFieldAttributes.Access defaultAccess =
|
||||||
(type instanceof AbstractClassMsType) ? ClassFieldAttributes.Access.PRIVATE
|
(type instanceof AbstractClassMsType) ? ClassFieldAttributes.Access.PRIVATE
|
||||||
: ClassFieldAttributes.Access.PUBLIC;
|
: ClassFieldAttributes.Access.PUBLIC;
|
||||||
|
@ -344,8 +338,7 @@ public class CompositeTypeApplier extends AbstractComplexTypeApplier {
|
||||||
// Does not use applier... goes straight to vftptr type
|
// Does not use applier... goes straight to vftptr type
|
||||||
private void addVftPtrs(Composite composite, CppCompositeType myClassType,
|
private void addVftPtrs(Composite composite, CppCompositeType myClassType,
|
||||||
List<AbstractVirtualFunctionTablePointerMsType> msVftPtrs, AbstractCompositeMsType type,
|
List<AbstractVirtualFunctionTablePointerMsType> msVftPtrs, AbstractCompositeMsType type,
|
||||||
List<DefaultPdbUniversalMember> myMembers)
|
List<DefaultPdbUniversalMember> myMembers) throws CancelledException, PdbException {
|
||||||
throws CancelledException, PdbException {
|
|
||||||
for (AbstractVirtualFunctionTablePointerMsType vftPtr : msVftPtrs) {
|
for (AbstractVirtualFunctionTablePointerMsType vftPtr : msVftPtrs) {
|
||||||
applicator.checkCancelled();
|
applicator.checkCancelled();
|
||||||
RecordNumber recordNumber = vftPtr.getPointerTypeRecordNumber();
|
RecordNumber recordNumber = vftPtr.getPointerTypeRecordNumber();
|
||||||
|
@ -487,8 +480,8 @@ public class CompositeTypeApplier extends AbstractComplexTypeApplier {
|
||||||
return done;
|
return done;
|
||||||
}
|
}
|
||||||
|
|
||||||
private DefaultPdbUniversalMember getNonStaticMember(Composite container,
|
private DefaultPdbUniversalMember getNonStaticMember(Composite container, Access defaultAccess,
|
||||||
Access defaultAccess, AbstractMemberMsType memberMsType, int ordinal)
|
AbstractMemberMsType memberMsType, int ordinal)
|
||||||
throws CancelledException, PdbException {
|
throws CancelledException, PdbException {
|
||||||
|
|
||||||
MsTypeApplier applier = applicator.getTypeApplier(memberMsType);
|
MsTypeApplier applier = applicator.getTypeApplier(memberMsType);
|
||||||
|
@ -524,8 +517,8 @@ public class CompositeTypeApplier extends AbstractComplexTypeApplier {
|
||||||
fieldApplier instanceof ArrayTypeApplier arrayApplier &&
|
fieldApplier instanceof ArrayTypeApplier arrayApplier &&
|
||||||
arrayApplier.isFlexibleArray(fieldType));
|
arrayApplier.isFlexibleArray(fieldType));
|
||||||
|
|
||||||
DefaultPdbUniversalMember member = new DefaultPdbUniversalMember(memberName, fieldDataType,
|
DefaultPdbUniversalMember member =
|
||||||
isZeroLengthArray, offset,
|
new DefaultPdbUniversalMember(memberName, fieldDataType, isZeroLengthArray, offset,
|
||||||
ClassFieldAttributes.convert(memberAttributes, defaultAccess), memberComment);
|
ClassFieldAttributes.convert(memberAttributes, defaultAccess), memberComment);
|
||||||
return member;
|
return member;
|
||||||
}
|
}
|
||||||
|
|
|
@ -180,6 +180,7 @@ public class DefaultPdbApplicator implements PdbApplicator {
|
||||||
|
|
||||||
private PdbApplicatorOptions applicatorOptions;
|
private PdbApplicatorOptions applicatorOptions;
|
||||||
private MessageLog log;
|
private MessageLog log;
|
||||||
|
private TaskMonitor monitor;
|
||||||
private CancelOnlyWrappingTaskMonitor cancelOnlyWrappingMonitor;
|
private CancelOnlyWrappingTaskMonitor cancelOnlyWrappingMonitor;
|
||||||
|
|
||||||
//==============================================================================================
|
//==============================================================================================
|
||||||
|
@ -247,15 +248,18 @@ public class DefaultPdbApplicator implements PdbApplicator {
|
||||||
* @param imageBaseParam address bases from which symbol addresses are based. If null, uses
|
* @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 applicatorOptionsParam {@link PdbApplicatorOptions} used for applying the PDB
|
||||||
|
* @param monitor the task monitor to use
|
||||||
* @param logParam the MessageLog to which to output messages
|
* @param logParam the MessageLog to which to output messages
|
||||||
* @throws PdbException if there was a problem processing the data
|
* @throws PdbException if there was a problem processing the data
|
||||||
*/
|
*/
|
||||||
public DefaultPdbApplicator(AbstractPdb pdb, Program programParam,
|
public DefaultPdbApplicator(AbstractPdb pdb, Program programParam,
|
||||||
DataTypeManager dataTypeManagerParam, Address imageBaseParam,
|
DataTypeManager dataTypeManagerParam, Address imageBaseParam,
|
||||||
PdbApplicatorOptions applicatorOptionsParam, MessageLog logParam) throws PdbException {
|
PdbApplicatorOptions applicatorOptionsParam, TaskMonitor monitor, MessageLog logParam)
|
||||||
|
throws PdbException {
|
||||||
|
|
||||||
Objects.requireNonNull(pdb, "pdb cannot be null");
|
Objects.requireNonNull(pdb, "pdb cannot be null");
|
||||||
this.pdb = pdb;
|
this.pdb = pdb;
|
||||||
|
this.monitor = (monitor != null) ? monitor : TaskMonitor.DUMMY;
|
||||||
|
|
||||||
// FIXME: should not support use of DataTypeManager-only since it will not have the correct
|
// FIXME: should not support use of DataTypeManager-only since it will not have the correct
|
||||||
// data organization if it corresponds to a data type archive. Need to evaluate archive
|
// data organization if it corresponds to a data type archive. Need to evaluate archive
|
||||||
|
@ -395,7 +399,6 @@ public class DefaultPdbApplicator implements PdbApplicator {
|
||||||
|
|
||||||
AddressSet disassembleAddresses = gatherAddressesForDisassembly();
|
AddressSet disassembleAddresses = gatherAddressesForDisassembly();
|
||||||
|
|
||||||
TaskMonitor monitor = getMonitor();
|
|
||||||
Listing listing = program.getListing();
|
Listing listing = program.getListing();
|
||||||
DisassemblerContextImpl seedContext =
|
DisassemblerContextImpl seedContext =
|
||||||
new DisassemblerContextImpl(program.getProgramContext());
|
new DisassemblerContextImpl(program.getProgramContext());
|
||||||
|
@ -447,7 +450,6 @@ public class DefaultPdbApplicator implements PdbApplicator {
|
||||||
|
|
||||||
//==============================================================================================
|
//==============================================================================================
|
||||||
private void processTypes() throws CancelledException, PdbException {
|
private void processTypes() throws CancelledException, PdbException {
|
||||||
TaskMonitor monitor = getMonitor();
|
|
||||||
monitor.setMessage("PDB: Applying to DTM " + dataTypeManager.getName() + "...");
|
monitor.setMessage("PDB: Applying to DTM " + dataTypeManager.getName() + "...");
|
||||||
|
|
||||||
PdbResearch.initBreakPointRecordNumbers(); // for developmental debug
|
PdbResearch.initBreakPointRecordNumbers(); // for developmental debug
|
||||||
|
@ -469,9 +471,6 @@ public class DefaultPdbApplicator implements PdbApplicator {
|
||||||
|
|
||||||
// PdbResearch.developerDebugOrder(this, monitor);
|
// PdbResearch.developerDebugOrder(this, monitor);
|
||||||
|
|
||||||
Msg.info(this, "resolveCount: " + resolveCount);
|
|
||||||
Msg.info(this, "conflictCount: " + conflictCount);
|
|
||||||
|
|
||||||
// Currently, defining classes needs to have a program. When this is no longer true,
|
// Currently, defining classes needs to have a program. When this is no longer true,
|
||||||
// then this call can be performed with the data types only work.
|
// then this call can be performed with the data types only work.
|
||||||
if (program != null) {
|
if (program != null) {
|
||||||
|
@ -480,6 +479,9 @@ public class DefaultPdbApplicator implements PdbApplicator {
|
||||||
|
|
||||||
// Process typedefs, which are in the symbols.
|
// Process typedefs, which are in the symbols.
|
||||||
processGlobalTypdefSymbols();
|
processGlobalTypdefSymbols();
|
||||||
|
|
||||||
|
Msg.info(this, "resolveCount: " + resolveCount);
|
||||||
|
Msg.info(this, "conflictCount: " + conflictCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
//==============================================================================================
|
//==============================================================================================
|
||||||
|
@ -562,7 +564,7 @@ public class DefaultPdbApplicator implements PdbApplicator {
|
||||||
validateAndSetParameters(programParam, dataTypeManagerParam, imageBaseParam,
|
validateAndSetParameters(programParam, dataTypeManagerParam, imageBaseParam,
|
||||||
applicatorOptionsParam, logParam);
|
applicatorOptionsParam, logParam);
|
||||||
|
|
||||||
cancelOnlyWrappingMonitor = new CancelOnlyWrappingTaskMonitor(getMonitor());
|
cancelOnlyWrappingMonitor = new CancelOnlyWrappingTaskMonitor(monitor);
|
||||||
|
|
||||||
pdbPeHeaderInfoManager = new PdbPeHeaderInfoManager(this);
|
pdbPeHeaderInfoManager = new PdbPeHeaderInfoManager(this);
|
||||||
|
|
||||||
|
@ -675,7 +677,7 @@ public class DefaultPdbApplicator implements PdbApplicator {
|
||||||
* @throws CancelledException if monitor has been cancelled
|
* @throws CancelledException if monitor has been cancelled
|
||||||
*/
|
*/
|
||||||
void checkCancelled() throws CancelledException {
|
void checkCancelled() throws CancelledException {
|
||||||
getMonitor().checkCancelled();
|
monitor.checkCancelled();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -727,7 +729,7 @@ public class DefaultPdbApplicator implements PdbApplicator {
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public TaskMonitor getMonitor() {
|
public TaskMonitor getMonitor() {
|
||||||
return pdb.getMonitor();
|
return monitor;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -922,7 +924,13 @@ public class DefaultPdbApplicator implements PdbApplicator {
|
||||||
throw new PdbException("Type not completed for record: " + recordNumber + "; " +
|
throw new PdbException("Type not completed for record: " + recordNumber + "; " +
|
||||||
type.getClass().getSimpleName());
|
type.getClass().getSimpleName());
|
||||||
}
|
}
|
||||||
multiphaseResolver.process(recordNumber);
|
|
||||||
|
MsDataTypeApplier dataTypeApplier = (MsDataTypeApplier) getTypeApplier(recordNumber);
|
||||||
|
if (!dataTypeApplier.apply(type)) {
|
||||||
|
throw new PdbException(
|
||||||
|
"Problem creating Primitive data type for record: " + recordNumber);
|
||||||
|
}
|
||||||
|
|
||||||
dataType = getDataType(recordNumber);
|
dataType = getDataType(recordNumber);
|
||||||
if (dataType == null) {
|
if (dataType == null) {
|
||||||
throw new PdbException(
|
throw new PdbException(
|
||||||
|
@ -1132,16 +1140,15 @@ public class DefaultPdbApplicator implements PdbApplicator {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int num = tpi.getTypeIndexMaxExclusive() - tpi.getTypeIndexMin();
|
int num = tpi.getTypeIndexMaxExclusive() - tpi.getTypeIndexMin();
|
||||||
TaskMonitor monitor = getMonitor();
|
monitor.initialize(2 * num); // progress updated in MultiphaseResolver; 2x per record
|
||||||
monitor.initialize(num);
|
|
||||||
monitor.setMessage("PDB: Processing " + num + " data type components...");
|
monitor.setMessage("PDB: Processing " + num + " data type components...");
|
||||||
for (int indexNumber = tpi.getTypeIndexMin(); indexNumber < tpi
|
for (int indexNumber = tpi.getTypeIndexMin(); indexNumber < tpi
|
||||||
.getTypeIndexMaxExclusive(); indexNumber++) {
|
.getTypeIndexMaxExclusive(); indexNumber++) {
|
||||||
monitor.checkCancelled();
|
monitor.checkCancelled();
|
||||||
RecordNumber recordNumber = RecordNumber.typeRecordNumber(indexNumber);
|
RecordNumber recordNumber = RecordNumber.typeRecordNumber(indexNumber);
|
||||||
RecordNumber mappedNumber = getMappedRecordNumber(recordNumber);
|
RecordNumber mappedNumber = getMappedRecordNumber(recordNumber);
|
||||||
multiphaseResolver.process(mappedNumber);
|
multiphaseResolver.process(mappedNumber, monitor);
|
||||||
monitor.incrementProgress(1);
|
// Monitor progress is updated in the multiphasResolver
|
||||||
}
|
}
|
||||||
|
|
||||||
doCheck();
|
doCheck();
|
||||||
|
@ -1213,7 +1220,6 @@ public class DefaultPdbApplicator implements PdbApplicator {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int num = ipi.getTypeIndexMaxExclusive() - ipi.getTypeIndexMin();
|
int num = ipi.getTypeIndexMaxExclusive() - ipi.getTypeIndexMin();
|
||||||
TaskMonitor monitor = getMonitor();
|
|
||||||
monitor.initialize(num);
|
monitor.initialize(num);
|
||||||
monitor.setMessage("PDB: Processing " + num + " item type components...");
|
monitor.setMessage("PDB: Processing " + num + " item type components...");
|
||||||
for (int indexNumber = ipi.getTypeIndexMin(); indexNumber < ipi
|
for (int indexNumber = ipi.getTypeIndexMin(); indexNumber < ipi
|
||||||
|
@ -1244,8 +1250,7 @@ public class DefaultPdbApplicator implements PdbApplicator {
|
||||||
if (!(dataType instanceof DataTypeImpl)) {
|
if (!(dataType instanceof DataTypeImpl)) {
|
||||||
return dataType;
|
return dataType;
|
||||||
}
|
}
|
||||||
DataType resolved = getDataTypeManager().resolve(dataType,
|
DataType resolved = getDataTypeManager().resolve(dataType, null);
|
||||||
DataTypeConflictHandler.REPLACE_EMPTY_STRUCTS_OR_RENAME_AND_ADD_HANDLER);
|
|
||||||
resolveCount++;
|
resolveCount++;
|
||||||
if (DataTypeUtilities.isConflictDataType(resolved)) {
|
if (DataTypeUtilities.isConflictDataType(resolved)) {
|
||||||
conflictCount++;
|
conflictCount++;
|
||||||
|
@ -1486,7 +1491,6 @@ public class DefaultPdbApplicator implements PdbApplicator {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int totalCount = symbolGroup.size();
|
int totalCount = symbolGroup.size();
|
||||||
TaskMonitor monitor = getMonitor();
|
|
||||||
monitor.setMessage("PDB: Applying " + totalCount + " main symbol components...");
|
monitor.setMessage("PDB: Applying " + totalCount + " main symbol components...");
|
||||||
monitor.initialize(totalCount);
|
monitor.initialize(totalCount);
|
||||||
MsSymbolIterator iter = symbolGroup.getSymbolIterator();
|
MsSymbolIterator iter = symbolGroup.getSymbolIterator();
|
||||||
|
@ -1499,7 +1503,6 @@ public class DefaultPdbApplicator implements PdbApplicator {
|
||||||
}
|
}
|
||||||
PdbDebugInfo debugInfo = pdb.getDebugInfo();
|
PdbDebugInfo debugInfo = pdb.getDebugInfo();
|
||||||
int num = debugInfo.getNumModules();
|
int num = debugInfo.getNumModules();
|
||||||
TaskMonitor monitor = getMonitor();
|
|
||||||
monitor.setMessage("PDB: Deferred-applying module symbol components...");
|
monitor.setMessage("PDB: Deferred-applying module symbol components...");
|
||||||
monitor.initialize(num + 1); // add one because we doing 0 through num, inclusive
|
monitor.initialize(num + 1); // add one because we doing 0 through num, inclusive
|
||||||
AddressSet addresses = new AddressSet();
|
AddressSet addresses = new AddressSet();
|
||||||
|
@ -1522,7 +1525,6 @@ public class DefaultPdbApplicator implements PdbApplicator {
|
||||||
AddressSet getDisassembleAddressForModule(int moduleNumber, MsSymbolIterator iter)
|
AddressSet getDisassembleAddressForModule(int moduleNumber, MsSymbolIterator iter)
|
||||||
throws CancelledException {
|
throws CancelledException {
|
||||||
iter.initGet();
|
iter.initGet();
|
||||||
TaskMonitor monitor = getMonitor();
|
|
||||||
AddressSet addresses = new AddressSet();
|
AddressSet addresses = new AddressSet();
|
||||||
while (iter.hasNext()) {
|
while (iter.hasNext()) {
|
||||||
monitor.checkCancelled();
|
monitor.checkCancelled();
|
||||||
|
@ -1550,7 +1552,6 @@ public class DefaultPdbApplicator implements PdbApplicator {
|
||||||
if (debugInfo == null) {
|
if (debugInfo == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
TaskMonitor monitor = getMonitor();
|
|
||||||
monitor.setMessage("PDB: Deferred-applying module symbol components...");
|
monitor.setMessage("PDB: Deferred-applying module symbol components...");
|
||||||
int num = debugInfo.getNumModules();
|
int num = debugInfo.getNumModules();
|
||||||
monitor.initialize(num);
|
monitor.initialize(num);
|
||||||
|
@ -1571,7 +1572,6 @@ public class DefaultPdbApplicator implements PdbApplicator {
|
||||||
private void doDeferredModuleSymbolGroup(int moduleNumber, MsSymbolIterator iter)
|
private void doDeferredModuleSymbolGroup(int moduleNumber, MsSymbolIterator iter)
|
||||||
throws CancelledException {
|
throws CancelledException {
|
||||||
iter.initGet();
|
iter.initGet();
|
||||||
TaskMonitor monitor = getMonitor();
|
|
||||||
while (iter.hasNext()) {
|
while (iter.hasNext()) {
|
||||||
monitor.checkCancelled();
|
monitor.checkCancelled();
|
||||||
AbstractMsSymbol symbol = iter.peek();
|
AbstractMsSymbol symbol = iter.peek();
|
||||||
|
@ -1593,7 +1593,6 @@ public class DefaultPdbApplicator implements PdbApplicator {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int num = debugInfo.getNumModules();
|
int num = debugInfo.getNumModules();
|
||||||
TaskMonitor monitor = getMonitor();
|
|
||||||
monitor.setMessage("PDB: Applying module symbol components...");
|
monitor.setMessage("PDB: Applying module symbol components...");
|
||||||
monitor.initialize(num);
|
monitor.initialize(num);
|
||||||
// Process symbols list for each module
|
// Process symbols list for each module
|
||||||
|
@ -1613,7 +1612,6 @@ public class DefaultPdbApplicator implements PdbApplicator {
|
||||||
private void processSymbolGroup(int moduleNumber, MsSymbolIterator iter)
|
private void processSymbolGroup(int moduleNumber, MsSymbolIterator iter)
|
||||||
throws CancelledException {
|
throws CancelledException {
|
||||||
iter.initGet();
|
iter.initGet();
|
||||||
TaskMonitor monitor = getMonitor();
|
|
||||||
while (iter.hasNext()) {
|
while (iter.hasNext()) {
|
||||||
monitor.checkCancelled();
|
monitor.checkCancelled();
|
||||||
procSymNew(iter);
|
procSymNew(iter);
|
||||||
|
@ -1642,7 +1640,6 @@ public class DefaultPdbApplicator implements PdbApplicator {
|
||||||
}
|
}
|
||||||
|
|
||||||
PublicSymbolInformation publicSymbolInformation = debugInfo.getPublicSymbolInformation();
|
PublicSymbolInformation publicSymbolInformation = debugInfo.getPublicSymbolInformation();
|
||||||
TaskMonitor monitor = getMonitor();
|
|
||||||
monitor.setMessage("PDB: Applying public symbols...");
|
monitor.setMessage("PDB: Applying public symbols...");
|
||||||
MsSymbolIterator iter = symbolGroup.getSymbolIterator();
|
MsSymbolIterator iter = symbolGroup.getSymbolIterator();
|
||||||
|
|
||||||
|
@ -1699,7 +1696,6 @@ public class DefaultPdbApplicator implements PdbApplicator {
|
||||||
// return;
|
// return;
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
TaskMonitor monitor = getMonitor();
|
|
||||||
monitor.setMessage("PDB: Applying global symbols...");
|
monitor.setMessage("PDB: Applying global symbols...");
|
||||||
GlobalSymbolInformation globalSymbolInformation = debugInfo.getGlobalSymbolInformation();
|
GlobalSymbolInformation globalSymbolInformation = debugInfo.getGlobalSymbolInformation();
|
||||||
// MsSymbolIterator iter = symbolGroup.getSymbolIterator();
|
// MsSymbolIterator iter = symbolGroup.getSymbolIterator();
|
||||||
|
@ -1721,6 +1717,8 @@ public class DefaultPdbApplicator implements PdbApplicator {
|
||||||
}
|
}
|
||||||
monitor.incrementProgress(1);
|
monitor.incrementProgress(1);
|
||||||
}
|
}
|
||||||
|
// TODO: need to create and update a count for only those really applied
|
||||||
|
//Msg.info(this, "GlobalSymbolComponentsCount: " + offsets.size());
|
||||||
|
|
||||||
// AbstractSymbolInformation.ModifiedOffsetIterator globalsIter =
|
// AbstractSymbolInformation.ModifiedOffsetIterator globalsIter =
|
||||||
// globalSymbolInformation.iterator();
|
// globalSymbolInformation.iterator();
|
||||||
|
@ -1754,7 +1752,6 @@ public class DefaultPdbApplicator implements PdbApplicator {
|
||||||
GlobalSymbolInformation globalSymbolInformation = debugInfo.getGlobalSymbolInformation();
|
GlobalSymbolInformation globalSymbolInformation = debugInfo.getGlobalSymbolInformation();
|
||||||
MsSymbolIterator iter = debugInfo.getSymbolIterator();
|
MsSymbolIterator iter = debugInfo.getSymbolIterator();
|
||||||
List<Long> offsets = globalSymbolInformation.getModifiedHashRecordSymbolOffsets();
|
List<Long> offsets = globalSymbolInformation.getModifiedHashRecordSymbolOffsets();
|
||||||
TaskMonitor monitor = getMonitor();
|
|
||||||
monitor.initialize(offsets.size(), "PDB: Performing deferred global symbols processing...");
|
monitor.initialize(offsets.size(), "PDB: Performing deferred global symbols processing...");
|
||||||
for (long offset : offsets) {
|
for (long offset : offsets) {
|
||||||
monitor.checkCancelled();
|
monitor.checkCancelled();
|
||||||
|
@ -1789,7 +1786,6 @@ public class DefaultPdbApplicator implements PdbApplicator {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
TaskMonitor monitor = getMonitor();
|
|
||||||
monitor.setMessage("PDB: Applying typedefs...");
|
monitor.setMessage("PDB: Applying typedefs...");
|
||||||
GlobalSymbolInformation globalSymbolInformation = debugInfo.getGlobalSymbolInformation();
|
GlobalSymbolInformation globalSymbolInformation = debugInfo.getGlobalSymbolInformation();
|
||||||
MsSymbolIterator iter = symbolGroup.getSymbolIterator();
|
MsSymbolIterator iter = symbolGroup.getSymbolIterator();
|
||||||
|
@ -1808,6 +1804,8 @@ public class DefaultPdbApplicator implements PdbApplicator {
|
||||||
}
|
}
|
||||||
monitor.incrementProgress(1);
|
monitor.incrementProgress(1);
|
||||||
}
|
}
|
||||||
|
// TODO: need to create and update a count for only those really applied
|
||||||
|
//Msg.info(this, "GlobalTypedefCount: " + offsets.size());
|
||||||
|
|
||||||
// AbstractSymbolInformation.ModifiedOffsetIterator globalsIter =
|
// AbstractSymbolInformation.ModifiedOffsetIterator globalsIter =
|
||||||
// globalSymbolInformation.iterator();
|
// globalSymbolInformation.iterator();
|
||||||
|
@ -1851,7 +1849,6 @@ public class DefaultPdbApplicator implements PdbApplicator {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
TaskMonitor monitor = getMonitor();
|
|
||||||
Set<Long> offsetsRemaining = symbolGroup.getOffsets();
|
Set<Long> offsetsRemaining = symbolGroup.getOffsets();
|
||||||
for (long off : debugInfo.getPublicSymbolInformation()
|
for (long off : debugInfo.getPublicSymbolInformation()
|
||||||
.getModifiedHashRecordSymbolOffsets()) {
|
.getModifiedHashRecordSymbolOffsets()) {
|
||||||
|
@ -1913,7 +1910,6 @@ public class DefaultPdbApplicator implements PdbApplicator {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
TaskMonitor monitor = getMonitor();
|
|
||||||
monitor.setMessage("PDB: Applying " + symbolGroup.size() + " linker symbol components...");
|
monitor.setMessage("PDB: Applying " + symbolGroup.size() + " linker symbol components...");
|
||||||
monitor.initialize(symbolGroup.size());
|
monitor.initialize(symbolGroup.size());
|
||||||
|
|
||||||
|
@ -1955,7 +1951,6 @@ public class DefaultPdbApplicator implements PdbApplicator {
|
||||||
SymbolGroup symbolGroup = getSymbolGroupForModule(linkerModuleNumber);
|
SymbolGroup symbolGroup = getSymbolGroupForModule(linkerModuleNumber);
|
||||||
if (symbolGroup != null) {
|
if (symbolGroup != null) {
|
||||||
|
|
||||||
TaskMonitor monitor = getMonitor();
|
|
||||||
monitor.initialize(symbolGroup.size());
|
monitor.initialize(symbolGroup.size());
|
||||||
MsSymbolIterator iter = symbolGroup.getSymbolIterator();
|
MsSymbolIterator iter = symbolGroup.getSymbolIterator();
|
||||||
int numCompileSymbols = 0;
|
int numCompileSymbols = 0;
|
||||||
|
@ -2012,7 +2007,6 @@ public class DefaultPdbApplicator implements PdbApplicator {
|
||||||
|
|
||||||
int totalCount = 0;
|
int totalCount = 0;
|
||||||
int num = debugInfo.getNumModules();
|
int num = debugInfo.getNumModules();
|
||||||
TaskMonitor monitor = getMonitor();
|
|
||||||
for (int index = 1; index <= num; index++) {
|
for (int index = 1; index <= num; index++) {
|
||||||
monitor.checkCancelled();
|
monitor.checkCancelled();
|
||||||
if (index == linkerModuleNumber) {
|
if (index == linkerModuleNumber) {
|
||||||
|
@ -2132,7 +2126,6 @@ public class DefaultPdbApplicator implements PdbApplicator {
|
||||||
//==============================================================================================
|
//==============================================================================================
|
||||||
private void defineClasses() throws CancelledException {
|
private void defineClasses() throws CancelledException {
|
||||||
// create namespace and classes in an ordered fashion use tree map
|
// create namespace and classes in an ordered fashion use tree map
|
||||||
TaskMonitor monitor = getMonitor();
|
|
||||||
monitor.initialize(isClassByNamespace.size());
|
monitor.initialize(isClassByNamespace.size());
|
||||||
monitor.setMessage("PDB: Defining classes...");
|
monitor.setMessage("PDB: Defining classes...");
|
||||||
for (Map.Entry<SymbolPath, Boolean> entry : isClassByNamespace.entrySet()) {
|
for (Map.Entry<SymbolPath, Boolean> entry : isClassByNamespace.entrySet()) {
|
||||||
|
|
|
@ -20,19 +20,19 @@ import java.util.Map;
|
||||||
|
|
||||||
import ghidra.app.util.bin.format.pdb2.pdbreader.*;
|
import ghidra.app.util.bin.format.pdb2.pdbreader.*;
|
||||||
import ghidra.app.util.bin.format.pdb2.pdbreader.type.AbstractMsType;
|
import ghidra.app.util.bin.format.pdb2.pdbreader.type.AbstractMsType;
|
||||||
import ghidra.program.model.data.*;
|
import ghidra.program.model.data.BitFieldDataType;
|
||||||
|
import ghidra.program.model.data.DataType;
|
||||||
import ghidra.util.exception.AssertException;
|
import ghidra.util.exception.AssertException;
|
||||||
import ghidra.util.exception.CancelledException;
|
import ghidra.util.exception.CancelledException;
|
||||||
import ghidra.util.task.TaskMonitor;
|
import ghidra.util.task.TaskMonitor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Performs appropriated multiple passes on data types to get theme filled in and resolved
|
* Performs appropriate multiple passes on data types to get theme filled in and resolved
|
||||||
*/
|
*/
|
||||||
public class MultiphaseDataTypeResolver {
|
public class MultiphaseDataTypeResolver {
|
||||||
|
|
||||||
private DefaultPdbApplicator applicator;
|
private DefaultPdbApplicator applicator;
|
||||||
private AbstractPdb pdb;
|
private AbstractPdb pdb;
|
||||||
private TaskMonitor monitor;
|
|
||||||
|
|
||||||
private RecordStack todoStack;
|
private RecordStack todoStack;
|
||||||
private RecordStack resolveStack;
|
private RecordStack resolveStack;
|
||||||
|
@ -40,7 +40,6 @@ public class MultiphaseDataTypeResolver {
|
||||||
public MultiphaseDataTypeResolver(DefaultPdbApplicator applicator) {
|
public MultiphaseDataTypeResolver(DefaultPdbApplicator applicator) {
|
||||||
this.applicator = applicator;
|
this.applicator = applicator;
|
||||||
this.pdb = applicator.getPdb();
|
this.pdb = applicator.getPdb();
|
||||||
this.monitor = applicator.getMonitor();
|
|
||||||
todoStack = new RecordStack();
|
todoStack = new RecordStack();
|
||||||
resolveStack = new RecordStack();
|
resolveStack = new RecordStack();
|
||||||
}
|
}
|
||||||
|
@ -50,10 +49,12 @@ public class MultiphaseDataTypeResolver {
|
||||||
* type. Deals with cyclic dependencies and ultimately stores resolved (in most cases)
|
* type. Deals with cyclic dependencies and ultimately stores resolved (in most cases)
|
||||||
* types in the DefaultPdbApplicator types map
|
* types in the DefaultPdbApplicator types map
|
||||||
* @param recordNumber the record number
|
* @param recordNumber the record number
|
||||||
|
* @param monitor the task monitor to use
|
||||||
* @throws PdbException upon processing error
|
* @throws PdbException upon processing error
|
||||||
* @throws CancelledException upon user cancellation
|
* @throws CancelledException upon user cancellation
|
||||||
*/
|
*/
|
||||||
void process(RecordNumber recordNumber) throws PdbException, CancelledException {
|
void process(RecordNumber recordNumber, TaskMonitor monitor)
|
||||||
|
throws PdbException, CancelledException {
|
||||||
|
|
||||||
// If found in the applicator map then the type is completed.
|
// If found in the applicator map then the type is completed.
|
||||||
if (applicator.getDataType(recordNumber) != null) {
|
if (applicator.getDataType(recordNumber) != null) {
|
||||||
|
@ -81,6 +82,9 @@ public class MultiphaseDataTypeResolver {
|
||||||
}
|
}
|
||||||
todoStack.pop();
|
todoStack.pop();
|
||||||
resolveStack.push(recordToProcess);
|
resolveStack.push(recordToProcess);
|
||||||
|
// only update when popped; 1st of 2 monitor updates; monitor count was
|
||||||
|
// initialized in DefaultPdbApplicator.processAndResolveDataTypesSequentially()
|
||||||
|
monitor.incrementProgress(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// If set true above, location where one might do conditional: todoStack.setDebug(false)
|
// If set true above, location where one might do conditional: todoStack.setDebug(false)
|
||||||
|
@ -89,11 +93,17 @@ public class MultiphaseDataTypeResolver {
|
||||||
while ((recordToProcess = resolveStack.pop()) != null) {
|
while ((recordToProcess = resolveStack.pop()) != null) {
|
||||||
monitor.checkCancelled();
|
monitor.checkCancelled();
|
||||||
DataType dataType = applicator.getDataType(recordToProcess);
|
DataType dataType = applicator.getDataType(recordToProcess);
|
||||||
// Resolve and re-store most data types
|
// Resolve and re-store most types. Normally we wouldn't want to resolve
|
||||||
if (!(dataType instanceof PointerDataType || dataType instanceof BitFieldDataType)) {
|
// pointer types, but here it is preferred while we have the types in hand the the
|
||||||
|
// PDB would have a type record if it wasn't used somewhere here or as the referred-to
|
||||||
|
// type of a typedef.
|
||||||
|
if (!(dataType instanceof BitFieldDataType)) {
|
||||||
dataType = applicator.resolve(dataType);
|
dataType = applicator.resolve(dataType);
|
||||||
applicator.putDataType(recordToProcess, dataType);
|
applicator.putDataType(recordToProcess, dataType);
|
||||||
}
|
}
|
||||||
|
// 2nd of 2 monitor updates; monitor count was initialized in
|
||||||
|
// DefaultPdbApplicator.processAndResolveDataTypesSequentially()
|
||||||
|
monitor.incrementProgress(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -152,6 +162,7 @@ public class MultiphaseDataTypeResolver {
|
||||||
RecordNode tail;
|
RecordNode tail;
|
||||||
boolean debug;
|
boolean debug;
|
||||||
StringBuilder debugBuilder;
|
StringBuilder debugBuilder;
|
||||||
|
long numNodes;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor for new record stack
|
* Constructor for new record stack
|
||||||
|
@ -165,6 +176,7 @@ public class MultiphaseDataTypeResolver {
|
||||||
head.prev = tail;
|
head.prev = tail;
|
||||||
tail.next = head;
|
tail.next = head;
|
||||||
tail.prev = null;
|
tail.prev = null;
|
||||||
|
numNodes = 0L; // does not count HEAD/TAIL special nodes
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -205,6 +217,7 @@ public class MultiphaseDataTypeResolver {
|
||||||
debugBuilder.append("\n");
|
debugBuilder.append("\n");
|
||||||
}
|
}
|
||||||
map.put(recordNumber, node);
|
map.put(recordNumber, node);
|
||||||
|
numNodes++;
|
||||||
}
|
}
|
||||||
else { // already exists in non-top-of-stack position
|
else { // already exists in non-top-of-stack position
|
||||||
removeNodeLinkage(node);
|
removeNodeLinkage(node);
|
||||||
|
@ -235,6 +248,7 @@ public class MultiphaseDataTypeResolver {
|
||||||
}
|
}
|
||||||
removeNodeLinkage(node);
|
removeNodeLinkage(node);
|
||||||
map.remove(node.recordNumber);
|
map.remove(node.recordNumber);
|
||||||
|
numNodes--;
|
||||||
if (debug) {
|
if (debug) {
|
||||||
debugBuilder.append(" pop:");
|
debugBuilder.append(" pop:");
|
||||||
debugBuilder.append(node.recordNumber);
|
debugBuilder.append(node.recordNumber);
|
||||||
|
@ -289,6 +303,7 @@ public class MultiphaseDataTypeResolver {
|
||||||
int count = 0;
|
int count = 0;
|
||||||
RecordNode node = head.prev;
|
RecordNode node = head.prev;
|
||||||
StringBuilder builder = new StringBuilder();
|
StringBuilder builder = new StringBuilder();
|
||||||
|
builder.append(numNodes + ":");
|
||||||
builder.append('[');
|
builder.append('[');
|
||||||
while (node != tail && count < TO_STRING_LIMIT) {
|
while (node != tail && count < TO_STRING_LIMIT) {
|
||||||
if (count != 0) {
|
if (count != 0) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue