diff --git a/Ghidra/Features/PDB/src/main/java/ghidra/app/plugin/core/analysis/PdbUniversalAnalyzer.java b/Ghidra/Features/PDB/src/main/java/ghidra/app/plugin/core/analysis/PdbUniversalAnalyzer.java index 4aace3fc2f..78aab73804 100644 --- a/Ghidra/Features/PDB/src/main/java/ghidra/app/plugin/core/analysis/PdbUniversalAnalyzer.java +++ b/Ghidra/Features/PDB/src/main/java/ghidra/app/plugin/core/analysis/PdbUniversalAnalyzer.java @@ -255,10 +255,9 @@ public class PdbUniversalAnalyzer extends AbstractAnalyzer { PdbProgramAttributes programAttributes = new PdbProgramAttributes(program); if (programAttributes.isPdbLoaded()) { - Msg.info(this, "Skipping PDB analysis since it has previouslu run."); - Msg.info(this, - ">> Clear 'PDB Loaded' program property or use Load PDB action if " + - "additional PDB processing required."); + Msg.info(this, "Skipping PDB analysis since it has previously run."); + Msg.info(this, ">> Clear 'PDB Loaded' program property or use Load PDB action if " + + "additional PDB processing required."); return true; } @@ -361,8 +360,8 @@ public class PdbUniversalAnalyzer extends AbstractAnalyzer { options.registerOption(OPTION_NAME_FORCELOAD_FILE, OptionType.FILE_TYPE, DEFAULT_FORCE_LOAD_FILE, null, OPTION_DESCRIPTION_FORCELOAD_FILE); } - options.registerOption(OPTION_NAME_SYMBOLPATH, OptionType.FILE_TYPE, - symbolsRepositoryDir, null, OPTION_DESCRIPTION_SYMBOLPATH); + options.registerOption(OPTION_NAME_SYMBOLPATH, OptionType.FILE_TYPE, symbolsRepositoryDir, + null, OPTION_DESCRIPTION_SYMBOLPATH); options.registerOption(OPTION_NAME_INCLUDE_PE_PDB_PATH, includePeSpecifiedPdbPath, null, OPTION_DESCRIPTION_INCLUDE_PE_PDB_PATH); diff --git a/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/PdbReaderMetrics.java b/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/PdbReaderMetrics.java index eac54494f7..dcedf173fa 100644 --- a/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/PdbReaderMetrics.java +++ b/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/PdbReaderMetrics.java @@ -23,7 +23,7 @@ import ghidra.app.util.bin.format.pdb2.pdbreader.type.AbstractMsType; /** * Metrics captured during the parsing and interpreting of a PDB. This is a Ghidra class * separate from the PDB API that we have crafted to help us quantify and qualify metatdata - * about the PDB. + * about the PDB. */ public class PdbReaderMetrics { @@ -919,8 +919,6 @@ public class PdbReaderMetrics { // Not sure what to do here. What are records in this range? // Worse is when it was originally a TYPE with high bit set. Why would it // just not be given a non-set high bit if primitive. - int a = 1; - a = a + 1; //witnessPrimitive(recordNumber.getNumber()); } break; diff --git a/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/symbol/AbstractManagedProcedureMsSymbol.java b/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/symbol/AbstractManagedProcedureMsSymbol.java index f7267375e8..33c53a7084 100644 --- a/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/symbol/AbstractManagedProcedureMsSymbol.java +++ b/Ghidra/Features/PDB/src/main/java/ghidra/app/util/bin/format/pdb2/pdbreader/symbol/AbstractManagedProcedureMsSymbol.java @@ -23,7 +23,8 @@ import ghidra.app.util.bin.format.pdb2.pdbreader.*; * Note: we do not necessarily understand each of these symbol type classes. Refer to the * base class for more information. */ -public abstract class AbstractManagedProcedureMsSymbol extends AbstractMsSymbol { +public abstract class AbstractManagedProcedureMsSymbol extends AbstractMsSymbol + implements AddressMsSymbol, NameMsSymbol { protected long parentPointer; protected long endPointer; @@ -79,4 +80,103 @@ public abstract class AbstractManagedProcedureMsSymbol extends AbstractMsSymbol builder.append(String.format(" Return Reg: %s\n", registerContainingReturnValue)); } + /** + * Returns the parent pointer. + * @return Parent pointer. + */ + public long getParentPointer() { + return parentPointer; + } + + /** + * Returns the end pointer. + * @return End pointer. + */ + public long getEndPointer() { + return endPointer; + } + + /** + * Returns the next pointer. + * @return next pointer. + */ + public long getNextPointer() { + return nextPointer; + } + + /** + * Returns the procedure length. + * @return Length. + */ + public long getProcedureLength() { + return procedureLength; + } + + /** + * Returns the debug start offset. + * @return Debug start offset. + */ + public long getDebugStartOffset() { + return debugStartOffset; + } + + /** + * Returns the debug end offset. + * @return Debug end offset. + */ + public long getDebugEndOffset() { + return debugEndOffset; + } + + /** + * Returns the offset. + * @return Offset. + */ + @Override + public long getOffset() { + return symbolOffset; + } + + /** + * Returns the segment. + * @return Segment. + */ + @Override + public int getSegment() { + return symbolSegment; + } + + /** + * Returns the {@link ProcedureFlags}. + * @return Procedure flags. + */ + public ProcedureFlags getFlags() { + return procedureFlags; + } + + /** + * Returns the procedure name. + * @return Name. + */ + @Override + public String getName() { + return name; + } + + /** + * Returns the token. + * @return token. + */ + public long getToken() { + return token; + } + + /** + * Returns the register containing the return value + * @return the register. + */ + public RegisterName getReturnRegister() { + return registerContainingReturnValue; + } + } diff --git a/Ghidra/Features/PDB/src/main/java/ghidra/app/util/pdb/pdbapplicator/BlockSymbolApplier.java b/Ghidra/Features/PDB/src/main/java/ghidra/app/util/pdb/pdbapplicator/BlockSymbolApplier.java index 949da49b52..98cefa55c2 100644 --- a/Ghidra/Features/PDB/src/main/java/ghidra/app/util/pdb/pdbapplicator/BlockSymbolApplier.java +++ b/Ghidra/Features/PDB/src/main/java/ghidra/app/util/pdb/pdbapplicator/BlockSymbolApplier.java @@ -58,10 +58,20 @@ public class BlockSymbolApplier extends MsSymbolApplier { @Override void manageBlockNesting(MsSymbolApplier applierParam) { + Address address = applicator.getAddress(symbol); if (applierParam instanceof FunctionSymbolApplier) { FunctionSymbolApplier functionSymbolApplier = (FunctionSymbolApplier) applierParam; - Address address = applicator.getAddress(symbol); functionSymbolApplier.beginBlock(address, symbol.getName(), symbol.getLength()); } + else if (applierParam instanceof SeparatedCodeSymbolApplier) { + SeparatedCodeSymbolApplier separatedCodeSymbolApplier = + (SeparatedCodeSymbolApplier) applierParam; + separatedCodeSymbolApplier.beginBlock(address); + } + else if (applierParam instanceof ManagedProcedureSymbolApplier) { + ManagedProcedureSymbolApplier procedureSymbolApplier = + (ManagedProcedureSymbolApplier) applierParam; + procedureSymbolApplier.beginBlock(address, symbol.getName(), symbol.getLength()); + } } } diff --git a/Ghidra/Features/PDB/src/main/java/ghidra/app/util/pdb/pdbapplicator/CppCompositeType.java b/Ghidra/Features/PDB/src/main/java/ghidra/app/util/pdb/pdbapplicator/CppCompositeType.java index 13cbb5d41d..897cccf3ac 100644 --- a/Ghidra/Features/PDB/src/main/java/ghidra/app/util/pdb/pdbapplicator/CppCompositeType.java +++ b/Ghidra/Features/PDB/src/main/java/ghidra/app/util/pdb/pdbapplicator/CppCompositeType.java @@ -309,7 +309,7 @@ public class CppCompositeType { * 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. + * when trying to place vbptr members. Not all of these methods are used too. * @param isFlexibleArray TODO */ public void insertMember(String memberName, DataType dataType, boolean isFlexibleArray, @@ -583,8 +583,7 @@ public class CppCompositeType { return builder.toString(); } - public ObjectOrientedClassLayout getLayout( - ObjectOrientedClassLayout layoutOptions) { + public ObjectOrientedClassLayout getLayout(ObjectOrientedClassLayout layoutOptions) { if (classLayout == null) { classLayout = determineClassLayout(layoutOptions); } @@ -644,8 +643,8 @@ public class CppCompositeType { //---------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------- - public void createVbtBasedLayout(ObjectOrientedClassLayout layoutOptions, - VbtManager vbtManager, TaskMonitor monitor) throws PdbException, CancelledException { + public void createVbtBasedLayout(ObjectOrientedClassLayout layoutOptions, VbtManager vbtManager, + TaskMonitor monitor) throws PdbException, CancelledException { CategoryPath cn; hasDirect = false; switch (getLayout(layoutOptions)) { @@ -699,8 +698,7 @@ public class CppCompositeType { } directClassLength = getCompositeLength(directDataType); } - if (getLayout( - layoutOptions) == ObjectOrientedClassLayout.SIMPLE_COMPLEX) { + if (getLayout(layoutOptions) == ObjectOrientedClassLayout.SIMPLE_COMPLEX) { // Not using the dummy/direct type (only used it to get the // directClassLength), so remove it and add the members to the main // type instead. @@ -836,8 +834,7 @@ public class CppCompositeType { } directClassLength = getCompositeLength(directDataType); } - if (getLayout( - layoutOptions) == ObjectOrientedClassLayout.SIMPLE_COMPLEX) { + if (getLayout(layoutOptions) == ObjectOrientedClassLayout.SIMPLE_COMPLEX) { // Not using the dummy/direct type (only used it to get the // directClassLength), so remove it and add the members to the main // type instead. @@ -947,8 +944,6 @@ public class CppCompositeType { throws PdbException { if (placeholderVirtualBaseTables.size() > 1) { // study this. - int a = 1; - a = a + 1; } boolean allVbtFound = true; @@ -957,8 +952,6 @@ public class CppCompositeType { PlaceholderVirtualBaseTable table = tableEntry.getValue(); if (!table.validateOffset()) { // TODO study this. - int a = 1; - a = a + 1; } DataType vbptr = getVbptrDataType(dtm, vbtManager, table); allVbtFound &= @@ -1153,7 +1146,7 @@ public class CppCompositeType { // // If last base is empty, then its comment and any accumulated to this point // // will not be seen (not applied to a PdbMember). TODO: Consider options, // // though we know we have left it in this state and are OK with it for now. -// // We have not considered fall-out from this. +// // We have not considered fall-out from this. // } // } @@ -1201,7 +1194,7 @@ public class CppCompositeType { // If last base is empty, then its comment and any accumulated to this point // will not be seen (not applied to a PdbMember). TODO: Consider options, // though we know we have left it in this state and are OK with it for now. - // We have not considered fall-out from this. + // We have not considered fall-out from this. } } @@ -1260,7 +1253,7 @@ public class CppCompositeType { // If last base is empty, then its comment and any accumulated to this point // will not be seen (not applied to a PdbMember). TODO: Consider options, // though we know we have left it in this state and are OK with it for now. - // We have not considered fall-out from this. + // We have not considered fall-out from this. } } @@ -1314,7 +1307,7 @@ public class CppCompositeType { return new CategoryPath(cn, baseName); } - // TODO: + // TODO: // Taken from PdbUtil without change. Would have had to change access on class PdbUtil and // this ensureSize method to public to make it accessible. Can revert to using PdbUtil // once we move this new module from Contrib to Features/PDB. @@ -1352,8 +1345,7 @@ public class CppCompositeType { return attributes; } - ObjectOrientedClassLayout getLayoutMode( - ObjectOrientedClassLayout layoutOptions) { + ObjectOrientedClassLayout getLayoutMode(ObjectOrientedClassLayout layoutOptions) { return baseClassType.getLayout(layoutOptions); } @@ -1391,7 +1383,7 @@ public class CppCompositeType { } //---------------------------------------------------------------------------------------------- - // Syntactic description of base classes. + // Syntactic description of base classes. //---------------------------------------------------------------------------------------------- private class SyntacticBaseClass extends BaseClass { private SyntacticBaseClass(CppCompositeType baseClassType, @@ -1430,8 +1422,7 @@ public class CppCompositeType { Structure getLayout() { if (layout == null) { - int a = 1; - a = a + 1; + // consider what to do here... } return layout; } diff --git a/Ghidra/Features/PDB/src/main/java/ghidra/app/util/pdb/pdbapplicator/EndSymbolApplier.java b/Ghidra/Features/PDB/src/main/java/ghidra/app/util/pdb/pdbapplicator/EndSymbolApplier.java index c83ff267e2..6c7b35adf5 100644 --- a/Ghidra/Features/PDB/src/main/java/ghidra/app/util/pdb/pdbapplicator/EndSymbolApplier.java +++ b/Ghidra/Features/PDB/src/main/java/ghidra/app/util/pdb/pdbapplicator/EndSymbolApplier.java @@ -69,5 +69,10 @@ public class EndSymbolApplier extends MsSymbolApplier { (SeparatedCodeSymbolApplier) applierParam; separatedCodeSymbolApplier.endBlock(); } + else if (applierParam instanceof ManagedProcedureSymbolApplier) { + ManagedProcedureSymbolApplier procedureSymbolApplier = + (ManagedProcedureSymbolApplier) applierParam; + procedureSymbolApplier.endBlock(); + } } } diff --git a/Ghidra/Features/PDB/src/main/java/ghidra/app/util/pdb/pdbapplicator/EnumTypeApplier.java b/Ghidra/Features/PDB/src/main/java/ghidra/app/util/pdb/pdbapplicator/EnumTypeApplier.java index fff603768f..3f2fb30e6f 100644 --- a/Ghidra/Features/PDB/src/main/java/ghidra/app/util/pdb/pdbapplicator/EnumTypeApplier.java +++ b/Ghidra/Features/PDB/src/main/java/ghidra/app/util/pdb/pdbapplicator/EnumTypeApplier.java @@ -129,8 +129,7 @@ public class EnumTypeApplier extends AbstractComplexTypeApplier { // MsProperty property = type.getMsProperty(); // if (property.isForwardReference()) { -// int a = 1; -// a = a + 1; +// // investigate this // } //// RecordNumber underlyingRecordNumber = type.getUnderlyingRecordNumber(); //// underlyingApplier = applicator.getApplier(underlyingRecordNumber); @@ -158,7 +157,7 @@ public class EnumTypeApplier extends AbstractComplexTypeApplier { // //TODO: can we set isSigned in here? ((PrimitiveMsType) underlying) // // TODO: there might be more // // TODO: investigate getSize() on AbstractMsType? -// // then: length = underlying.getSize(); +// // then: length = underlying.getSize(); // } // } // // Ghidra does not like size of zero. @@ -227,8 +226,7 @@ public class EnumTypeApplier extends AbstractComplexTypeApplier { // RecordNumber underlyingRecordNumber = type.getUnderlyingRecordNumber(); // MsProperty property = type.getMsProperty(); // if (property.isForwardReference()) { -// int a = 1; -// a = a + 1; +// // investigate this // } // underlyingApplier = applicator.getApplier(underlyingRecordNumber); // @@ -248,7 +246,7 @@ public class EnumTypeApplier extends AbstractComplexTypeApplier { // length = ((PrimitiveMsType) underlying).getTypeSize(); // // TODO: there might be more // // TODO: investigate getSize() on AbstractMsType? -// // then: length = underlying.getSize(); +// // then: length = underlying.getSize(); // } // } // // Ghidra does not like size of zero. diff --git a/Ghidra/Features/PDB/src/main/java/ghidra/app/util/pdb/pdbapplicator/ManagedProcedureSymbolApplier.java b/Ghidra/Features/PDB/src/main/java/ghidra/app/util/pdb/pdbapplicator/ManagedProcedureSymbolApplier.java new file mode 100644 index 0000000000..34ac56f640 --- /dev/null +++ b/Ghidra/Features/PDB/src/main/java/ghidra/app/util/pdb/pdbapplicator/ManagedProcedureSymbolApplier.java @@ -0,0 +1,506 @@ +/* ### + * IP: GHIDRA + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ghidra.app.util.pdb.pdbapplicator; + +import java.util.*; + +import ghidra.app.cmd.disassemble.DisassembleCommand; +import ghidra.app.cmd.function.CallDepthChangeInfo; +import ghidra.app.cmd.function.CreateFunctionCmd; +import ghidra.app.util.bin.format.pdb2.pdbreader.PdbException; +import ghidra.app.util.bin.format.pdb2.pdbreader.symbol.AbstractManagedProcedureMsSymbol; +import ghidra.app.util.bin.format.pdb2.pdbreader.symbol.AbstractMsSymbol; +import ghidra.app.util.bin.format.pe.cli.tables.CliAbstractTableRow; +import ghidra.app.util.bin.format.pe.cli.tables.CliTableMethodDef.CliMethodDefRow; +import ghidra.app.util.bin.format.pe.cli.tables.CliTableMethodImpl.CliMethodImplRow; +import ghidra.app.util.bin.format.pe.cli.tables.CliTableMethodSemantics.CliMethodSemanticsRow; +import ghidra.app.util.bin.format.pe.cli.tables.CliTableMethodSpec.CliMethodSpecRow; +import ghidra.app.util.pdb.pdbapplicator.SymbolGroup.AbstractMsSymbolIterator; +import ghidra.program.model.address.Address; +import ghidra.program.model.address.AddressSet; +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.exception.AssertException; +import ghidra.util.exception.CancelledException; +import ghidra.util.task.TaskMonitor; + +// NOTE: This class is currently just a stub applier that does not do much except try to +// protect the context of all of the other symbols around it. Mainly, it was not being +// processed in the past, but now does partial processing, in that it tries to maintain the +// integrity of the block nesting that we monitor. +// TODO: This class was started as a copy of FunctionSymbolApplier. As this is worked on, we +// need to determine if it can be a proper child of the class or if FunctionSymbolApplier +// should be adapted to handle both. Much of the code below, even if not yet used, can serve +// as a foundation for determining how we should process "Managed" procedures. +/** + * Applier for {@link AbstractManagedProcedureMsSymbol} symbols. + */ +public class ManagedProcedureSymbolApplier extends MsSymbolApplier { + + private static final String BLOCK_INDENT = " "; + + private AbstractManagedProcedureMsSymbol procedureSymbol; + + private Address specifiedAddress; + private Address address; + private Function function = null; + private long specifiedFrameSize = 0; + private long currentFrameSize = 0; + private BlockCommentsManager comments; + + private int symbolBlockNestingLevel; + private Address currentBlockAddress; + + // might not need this, but investigating whether it will help us. TODO remove? + private int baseParamOffset = 0; + +// private List stackVariableAppliers = new ArrayList<>(); + + private List 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 ManagedProcedureSymbolApplier(PdbApplicator applicator, AbstractMsSymbolIterator iter) + throws CancelledException { + super(applicator, iter); + AbstractMsSymbol abstractSymbol = iter.next(); + symbolBlockNestingLevel = 0; + comments = new BlockCommentsManager(); + currentBlockAddress = null; + + if (!(abstractSymbol instanceof AbstractManagedProcedureMsSymbol)) { + throw new AssertException( + "Invalid symbol type: " + abstractSymbol.getClass().getSimpleName()); + } + // TODO: Remove the witness call once we effectively process this class of symbols + // See that the applyTo() method is much unimplemented. + applicator.getPdbApplicatorMetrics().witnessCannotApplySymbolType(abstractSymbol); + procedureSymbol = (AbstractManagedProcedureMsSymbol) abstractSymbol; + specifiedAddress = applicator.getRawAddress(procedureSymbol); + address = applicator.getAddress(procedureSymbol); + + manageBlockNesting(this); + + while (notDone()) { + applicator.checkCanceled(); + MsSymbolApplier applier = applicator.getSymbolApplier(iter); + allAppliers.add(applier); + applier.manageBlockNesting(this); + } + } + + @Override + void manageBlockNesting(MsSymbolApplier applierParam) { + ManagedProcedureSymbolApplier procedureSymbolApplier = + (ManagedProcedureSymbolApplier) applierParam; + long start = procedureSymbol.getDebugStartOffset(); + long end = procedureSymbol.getDebugEndOffset(); + Address blockAddress = address.add(start); + long length = end - start; + procedureSymbolApplier.beginBlock(blockAddress, procedureSymbol.getName(), length); + } + + /** + * Returns the {@link Function} for this applier. + * @return the Function + */ + Function getFunction() { + return function; + } + + /** + * Returns the current frame size. + * @return the current frame size. + */ + long getCurrentFrameSize() { + return currentFrameSize; + } + + /** + * Returns the frame size as specified by the PDB + * @return the frame size. + */ + long getSpecifiedFrameSize() { + return specifiedFrameSize; + } + + /** + * Set the specified frame size. + * @param specifiedFrameSize the frame size. + */ + void setSpecifiedFrameSize(long specifiedFrameSize) { + this.specifiedFrameSize = specifiedFrameSize; + currentFrameSize = specifiedFrameSize; + } + + /** + * Get the function name + * @return the function name + */ + String getName() { + return procedureSymbol.getName(); + } + + @Override + void applyTo(MsSymbolApplier applyToApplier) { + // Do nothing. + } + + @Override + void apply() throws PdbException, CancelledException { + boolean result = applyTo(applicator.getCancelOnlyWrappingMonitor()); + if (result == false) { + throw new PdbException(this.getClass().getSimpleName() + ": failure at " + address + + " applying " + getName()); + } + } + + boolean applyTo(TaskMonitor monitor) throws PdbException, CancelledException { + if (applicator.isInvalidAddress(address, getName())) { + return false; + } + + // TODO: We do not know, yet, how/where to apply this. Need to wait for other .NET + // work to get done for loading. Have commented-out code below, but have added some + // functionality (laying down symbol). This file was somewhat copied from + // FunctionSymbolApplier. + // TODO: Also see the TODO in the constructor regarding the call to witness. + for (MsSymbolApplier applier : allAppliers) { + applier.applyTo(this); + } + + boolean functionSuccess = applyFunction(monitor); + if (functionSuccess == false) { + return false; + } +// registerChangeCalculator = new RegisterChangeCalculator(procedureSymbol, function, monitor); +// +// baseParamOffset = VariableUtilities.getBaseStackParamOffset(function); +// +// for (MsSymbolApplier applier : allAppliers) { +// applier.applyTo(this); +// } +// +// // comments +// long addressDelta = address.subtract(specifiedAddress); +// comments.applyTo(applicator.getProgram(), addressDelta); + + // line numbers + // TODO: not done yet +// ApplyLineNumbers applyLineNumbers = new ApplyLineNumbers(pdbParser, xmlParser, program); +// applyLineNumbers.applyTo(monitor, log); + + return true; + } + + Integer getRegisterPrologChange(Register register) { + return registerChangeCalculator.getRegChange(applicator, register); + } + + int getBaseParamOffset() { + return baseParamOffset; + } + + /** + * Sets a local variable (address, name, type) + * @param address Address of the variable. + * @param name name of the variable. + * @param dataType data type of the variable. + */ + void setLocalVariable(Address address, String name, DataType dataType) { + if (currentBlockAddress == null) { + return; // silently return. + } + // Currently just placing a comment. + String comment = getIndent(symbolBlockNestingLevel + 1) + "static local (stored at " + + address + ") " + dataType.getName() + " " + name; + comments.addPreComment(currentBlockAddress, comment); + } + + private boolean applyFunction(TaskMonitor monitor) { + Listing listing = applicator.getProgram().getListing(); + + applicator.createSymbol(address, getName(), true); + + function = listing.getFunctionAt(address); + if (function == null) { + function = createFunction(monitor); + } + if (function != null && !function.isThunk() && + (function.getSignatureSource() == SourceType.DEFAULT || + function.getSignatureSource() == SourceType.ANALYSIS)) { + // Set the function definition + setFunctionDefinition(monitor); + + } + if (function == null) { + return false; + } + + currentFrameSize = 0; + return true; + } + + private Function createFunction(TaskMonitor monitor) { + + // Does function already exist? + Function myFunction = applicator.getProgram().getListing().getFunctionAt(address); + if (myFunction != null) { + // Actually not sure if we should set to 0 or calculate from the function here. + // Need to investigate more, so at least keeping it as a separate 'else' for now. + return myFunction; + } + + // Disassemble + Instruction instr = applicator.getProgram().getListing().getInstructionAt(address); + if (instr == null) { + DisassembleCommand cmd = new DisassembleCommand(address, null, true); + cmd.applyTo(applicator.getProgram(), monitor); + } + + myFunction = createFunctionCommand(monitor); + + return myFunction; + } + + private boolean setFunctionDefinition(TaskMonitor monitor) { + if (procedureSymbol == null) { + // TODO: is there anything we can do with thunkSymbol? + // long x = thunkSymbol.getParentPointer(); + return true; + } + // Rest presumes procedureSymbol. + long token = procedureSymbol.getToken(); + int table = (int) (token >> 24) & 0xff; + int row = (int) (token & 0xffffff); + + //This is all under investigation at this time. + CliAbstractTableRow tableRow; + try { + tableRow = applicator.getCliTableRow(table, row); + if (tableRow instanceof CliMethodDefRow) { + CliMethodDefRow def = (CliMethodDefRow) tableRow; + // investigate what to do next + } + if (tableRow instanceof CliMethodImplRow) { + CliMethodImplRow def = (CliMethodImplRow) tableRow; + // investigate what to do next + } + if (tableRow instanceof CliMethodSemanticsRow) { + CliMethodSemanticsRow def = (CliMethodSemanticsRow) tableRow; + // investigate what to do next + } + if (tableRow instanceof CliMethodSpecRow) { + CliMethodSpecRow def = (CliMethodSpecRow) tableRow; + // investigate what to do next + } + else { + // investigate what to do next + } + } + catch (PdbException e) { + // do nothing for now... just investigating + return false; + } + + // TODO: something :) + +// +// RecordNumber typeRecordNumber = procedureSymbol.getTypeRecordNumber(); +// MsTypeApplier applier = applicator.getTypeApplier(typeRecordNumber); +// +// if (applier == null) { +// applicator.appendLogMsg("Error: Failed to resolve datatype RecordNumber " + +// typeRecordNumber + " at " + address); +// return false; +// } +// if (!(applier instanceof AbstractFunctionTypeApplier)) { +// if (!((applier instanceof PrimitiveTypeApplier) && +// ((PrimitiveTypeApplier) applier).isNoType())) { +// applicator.appendLogMsg("Error: Failed to resolve datatype RecordNumber " + +// typeRecordNumber + " at " + address); +// return false; +// } +// } +// +// DataType dataType = applier.getDataType(); +// // Since we know the applier is an AbstractionFunctionTypeApplier, then dataType is either +// // FunctionDefinition or no type (typedef). +// if (dataType instanceof FunctionDefinition) { +// FunctionDefinition def = (FunctionDefinition) dataType; +// ApplyFunctionSignatureCmd sigCmd = +// new ApplyFunctionSignatureCmd(address, def, SourceType.IMPORTED); +// if (!sigCmd.applyTo(applicator.getProgram(), monitor)) { +// applicator.appendLogMsg( +// "PDB Warning: Failed to apply signature to function at address " + address + +// " due to " + sigCmd.getStatusMsg() + "; dataType: " + def.getName()); +// return false; +// } +// } + return true; + } + + private Function createFunctionCommand(TaskMonitor monitor) { + CreateFunctionCmd funCmd = new CreateFunctionCmd(address); + if (!funCmd.applyTo(applicator.getProgram(), monitor)) { + applicator.appendLogMsg("Failed to apply function at address " + address.toString() + + "; attempting to use possible existing function"); + return applicator.getProgram().getListing().getFunctionAt(address); + } + return funCmd.getFunction(); + } + + private boolean notDone() { + return (symbolBlockNestingLevel > 0) && iter.hasNext(); + } + + int endBlock() { + if (--symbolBlockNestingLevel < 0) { + applicator.appendLogMsg( + "Block Nesting went negative for " + getName() + " at " + address); + } + if (symbolBlockNestingLevel == 0) { + //currentFunctionSymbolApplier = null; + } + return symbolBlockNestingLevel; + } + + void beginBlock(Address startAddress, String name, long length) { + + int nestingLevel = beginBlock(startAddress); + if (!applicator.getPdbApplicatorOptions().applyCodeScopeBlockComments()) { + return; + } + if (applicator.isInvalidAddress(startAddress, name)) { + return; + } + + String indent = getIndent(nestingLevel); + + String baseComment = "level " + nestingLevel + ", length " + length; + + String preComment = indent + "PDB: Block Beg, " + baseComment; + if (!name.isEmpty()) { + preComment += " (" + name + ")"; + } + comments.addPreComment(startAddress, preComment); + + String postComment = indent + "PDB: Block End, " + baseComment; + Address endAddress = startAddress.add(((length <= 0) ? 0 : length - 1)); + comments.addPostComment(endAddress, postComment); + } + + private int beginBlock(Address startAddress) { + currentBlockAddress = startAddress; + ++symbolBlockNestingLevel; + return symbolBlockNestingLevel; + } + + private String getIndent(int indentLevel) { + String indent = ""; + for (int i = 1; i < indentLevel; i++) { + indent += BLOCK_INDENT; + } + return indent; + } + + // Method copied from ApplyStackVariables (ghidra.app.util.bin.format.pdb package) + // on 20191119. TODO: Do we need something like this? + /** + * Get the stack offset after it settles down. + * @param monitor TaskMonitor + * @return stack offset that stack variables will be relative to. + * @throws CancelledException upon user cancellation. + */ + private int getFrameBaseOffset(TaskMonitor monitor) throws CancelledException { + + int retAddrSize = function.getProgram().getDefaultPointerSize(); + + if (retAddrSize != 8) { + // don't do this for 32 bit. + return -retAddrSize; // 32 bit has a -4 byte offset + } + + Register frameReg = function.getProgram().getCompilerSpec().getStackPointer(); + Address entryAddr = function.getEntryPoint(); + AddressSet scopeSet = new AddressSet(); + scopeSet.addRange(entryAddr, entryAddr.add(64)); + CallDepthChangeInfo valueChange = + new CallDepthChangeInfo(function, scopeSet, frameReg, monitor); + InstructionIterator instructions = + function.getProgram().getListing().getInstructions(scopeSet, true); + int max = 0; + while (instructions.hasNext()) { + monitor.checkCanceled(); + Instruction next = instructions.next(); + int newValue = valueChange.getDepth(next.getMinAddress()); + if (newValue < -(20 * 1024) || newValue > (20 * 1024)) { + continue; + } + if (Math.abs(newValue) > Math.abs(max)) { + max = newValue; + } + } + return max; + } + + private static class RegisterChangeCalculator { + + private Map registerChangeByRegisterName = new HashMap<>(); + private CallDepthChangeInfo callDepthChangeInfo; + private Address debugStart; + + private RegisterChangeCalculator(AbstractManagedProcedureMsSymbol procedureSymbol, + Function function, TaskMonitor monitor) throws CancelledException { + callDepthChangeInfo = createCallDepthChangInfo(procedureSymbol, function, monitor); + } + + private CallDepthChangeInfo createCallDepthChangInfo( + AbstractManagedProcedureMsSymbol procedureSymbol, Function function, + TaskMonitor monitor) throws CancelledException { + if (procedureSymbol == null) { + return null; + } + Register frameReg = function.getProgram().getCompilerSpec().getStackPointer(); + Address entryAddr = function.getEntryPoint(); + debugStart = entryAddr.add(procedureSymbol.getDebugStartOffset()); + AddressSet scopeSet = new AddressSet(); + scopeSet.addRange(entryAddr, debugStart); + return new CallDepthChangeInfo(function, scopeSet, frameReg, monitor); + } + + Integer getRegChange(PdbApplicator applicator, Register register) { + if (callDepthChangeInfo == null || register == null) { + return null; + } + Integer change = registerChangeByRegisterName.get(register); + if (change != null) { + return change; + } + change = callDepthChangeInfo.getRegDepth(debugStart, register); + registerChangeByRegisterName.put(register, change); + return change; + } + + } +} diff --git a/Ghidra/Features/PDB/src/main/java/ghidra/app/util/pdb/pdbapplicator/PdbApplicator.java b/Ghidra/Features/PDB/src/main/java/ghidra/app/util/pdb/pdbapplicator/PdbApplicator.java index 5d2d894236..3ff03557a6 100644 --- a/Ghidra/Features/PDB/src/main/java/ghidra/app/util/pdb/pdbapplicator/PdbApplicator.java +++ b/Ghidra/Features/PDB/src/main/java/ghidra/app/util/pdb/pdbapplicator/PdbApplicator.java @@ -15,9 +15,8 @@ */ package ghidra.app.util.pdb.pdbapplicator; -import java.util.*; - import java.math.BigInteger; +import java.util.*; import ghidra.app.cmd.label.SetLabelPrimaryCmd; import ghidra.app.util.NamespaceUtils; @@ -26,6 +25,7 @@ import ghidra.app.util.bin.format.pdb.PdbParserConstants; 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.bin.format.pe.cli.tables.CliAbstractTableRow; import ghidra.app.util.importer.MessageLog; import ghidra.app.util.pdb.PdbCategories; import ghidra.app.util.pdb.pdbapplicator.SymbolGroup.AbstractMsSymbolIterator; @@ -123,6 +123,8 @@ public class PdbApplicator { private PdbAddressManager pdbAddressManager; private List symbolGroups; + private PdbCliInfoManager pdbCliManagedInfoManager; + //============================================================================================== // If we have symbols and memory with VBTs in them, then a better VbtManager is created. VbtManager vbtManager; @@ -140,7 +142,7 @@ public class PdbApplicator { *
 	 *   false = simple namespace
 	 *   true = class namespace
-	 *  
+ * */ private Map isClassByNamespace; @@ -309,6 +311,9 @@ public class PdbApplicator { pdbApplicatorMetrics = new PdbApplicatorMetrics(); pdbAddressManager = new PdbAddressManager(this, imageBase); + + pdbCliManagedInfoManager = new PdbCliInfoManager(this); + symbolGroups = createSymbolGroups(); categoryUtils = setPdbCatogoryUtils(pdbFilename); @@ -414,6 +419,14 @@ public class PdbApplicator { log.appendMsg(message); } + /** + * Returns the MessageLog. + * @return the MessageLog + */ + MessageLog getMessageLog() { + return log; + } + /** * Puts message to {@link PdbLog} and to Msg.info() * @param originator a Logger instance, "this", or YourClass.class @@ -470,7 +483,7 @@ public class PdbApplicator { // Information for a putative PdbTypeApplicator: /** - * Returns the {@link DataTypeManager} associated with this analyzer. + * Returns the {@link DataTypeManager} associated with this analyzer. * @return DataTypeManager which this analyzer is using. */ DataTypeManager getDataTypeManager() { @@ -502,8 +515,8 @@ public class PdbApplicator { /** * Returns the {@link CategoryPath} for a typedef with with the give {@link SymbolPath} and - * module number; 1 <= moduleNumber <= {@link PdbDebugInfo#getNumModules()}, - * except that modeleNumber of 0 represents publics/globals. + * module number; 1 <= moduleNumber <= {@link PdbDebugInfo#getNumModules()}, + * except that modeleNumber of 0 represents publics/globals. * @param moduleNumber module number * @param symbolPath SymbolPath of the symbol * @return the CategoryPath @@ -910,6 +923,13 @@ public class PdbApplicator { pdbAddressManager.addMemorySectionRefinement(symbol); } + //============================================================================================== + // CLI-Managed infor methods. + //============================================================================================== + CliAbstractTableRow getCliTableRow(int tableNum, int rowNum) throws PdbException { + return pdbCliManagedInfoManager.getCliTableRow(tableNum, rowNum); + } + //============================================================================================== // Virtual-Base-Table-related methods. //============================================================================================== @@ -918,7 +938,7 @@ public class PdbApplicator { } //============================================================================================== - // + // //============================================================================================== Register getRegister(String pdbRegisterName) { return registerNameToRegisterMapper.getRegister(pdbRegisterName); @@ -1140,7 +1160,7 @@ public class PdbApplicator { num++; } } - appendLogMsg("Not processing linker symbols because linker module not found"); + pdbLogAndInfoMessage(this, "Not processing linker symbols because linker module not found"); return -1; } diff --git a/Ghidra/Features/PDB/src/main/java/ghidra/app/util/pdb/pdbapplicator/PdbCliInfoManager.java b/Ghidra/Features/PDB/src/main/java/ghidra/app/util/pdb/pdbapplicator/PdbCliInfoManager.java new file mode 100644 index 0000000000..d058a9d251 --- /dev/null +++ b/Ghidra/Features/PDB/src/main/java/ghidra/app/util/pdb/pdbapplicator/PdbCliInfoManager.java @@ -0,0 +1,93 @@ +/* ### + * IP: GHIDRA + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ghidra.app.util.pdb.pdbapplicator; + +import java.io.IOException; +import java.util.Objects; + +import generic.continues.GenericFactory; +import ghidra.app.util.bin.ByteProvider; +import ghidra.app.util.bin.MemoryByteProvider; +import ghidra.app.util.bin.format.pdb2.pdbreader.PdbException; +import ghidra.app.util.bin.format.pe.*; +import ghidra.app.util.bin.format.pe.PortableExecutable.SectionLayout; +import ghidra.app.util.bin.format.pe.cli.streams.CliStreamMetadata; +import ghidra.app.util.bin.format.pe.cli.tables.CliAbstractTable; +import ghidra.app.util.bin.format.pe.cli.tables.CliAbstractTableRow; +import ghidra.app.util.importer.MessageLogContinuesFactory; +import ghidra.program.model.listing.Program; + +/** + * Manages CLI-Managed information, the bounds of which we do not yet know. + */ +public class PdbCliInfoManager { + + private CliStreamMetadata metadataStream; + + /** + * Manager of CLI-related tables that we might need access to for PDB processing. + * @param applicator {@link PdbApplicator} for which this class is working. + */ + PdbCliInfoManager(PdbApplicator applicator) { + Objects.requireNonNull(applicator, "applicator may not be null"); + metadataStream = getCliStreamMetadata(applicator); + } + + public CliAbstractTableRow getCliTableRow(int tableNum, int rowNum) throws PdbException { + if (metadataStream == null) { + throw new PdbException("CliStreamMetadata is null"); + } + CliAbstractTable table = metadataStream.getTable(tableNum); + if (table == null) { + return null; + } + return table.getRow(rowNum); + } + + private CliStreamMetadata getCliStreamMetadata(PdbApplicator applicator) { + Program program = applicator.getProgram(); + if (program == null) { + return null; + } + + ByteProvider provider = new MemoryByteProvider(program.getMemory(), program.getImageBase()); + PortableExecutable pe = null; + try { + GenericFactory factory = MessageLogContinuesFactory.create(applicator.getMessageLog()); + pe = PortableExecutable.createPortableExecutable(factory, provider, + SectionLayout.MEMORY, true, true); + NTHeader ntHeader = pe.getNTHeader(); + OptionalHeader optionalHeader = ntHeader.getOptionalHeader(); + DataDirectory[] dataDirectory = optionalHeader.getDataDirectories(); + COMDescriptorDataDirectory comDir = + (COMDescriptorDataDirectory) dataDirectory[OptionalHeader.IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR]; + ImageCor20Header header = comDir.getHeader(); + return header.getMetadata().getMetadataRoot().getMetadataStream(); + } + catch (Exception e) { + applicator.pdbLogAndInfoMessage(this, "Unable to retrieve CliStreamMetadata"); + return null; + } + finally { + try { + provider.close(); + } + catch (IOException ioe) { + applicator.pdbLogAndInfoMessage(this, "Problem closing ByteProvider"); + } + } + } +} diff --git a/Ghidra/Features/PDB/src/main/java/ghidra/app/util/pdb/pdbapplicator/PdbResearch.java b/Ghidra/Features/PDB/src/main/java/ghidra/app/util/pdb/pdbapplicator/PdbResearch.java index 497c5b5883..ddc3441c8e 100644 --- a/Ghidra/Features/PDB/src/main/java/ghidra/app/util/pdb/pdbapplicator/PdbResearch.java +++ b/Ghidra/Features/PDB/src/main/java/ghidra/app/util/pdb/pdbapplicator/PdbResearch.java @@ -44,10 +44,16 @@ public class PdbResearch { private static Set developerDebugOrderIndexNumbers; //============================================================================================== + // This method exists so we can place breakpoints on call locations to it wherever we + // would like to break during debugging. + private static void doNothingSetBreakPointHere() { + // Do nothing. + } + /** * 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. + * {@link #checkBreak(int recordNumber)} in which we set a breakpoint on + * {@code #doNothingSetBreakPointHere();} to then allow us to debug into other code. */ static void initBreakPointRecordNumbers() { debugIndexNumbers = new TreeSet<>(); @@ -284,28 +290,28 @@ public class PdbResearch { // debugIndexNumbers.add(6236); // fwdref is 6168 // // // member of 6236 -// debugIndexNumbers.add(6251); // fwdref is 6220 +// debugIndexNumbers.add(6251); // fwdref is 6220 // // // member of 6251 // debugIndexNumbers.add(6263); // fwdref is 6237 // // // base class / member of 6263 -// debugIndexNumbers.add(6284); // fwdref is 6252 +// debugIndexNumbers.add(6284); // fwdref is 6252 // // // base class / member of 6284 -// debugIndexNumbers.add(6328); // fwdref is 6264 +// debugIndexNumbers.add(6328); // fwdref is 6264 // // // member of 6328 -// debugIndexNumbers.add(6335); // fwdref is 6285 +// debugIndexNumbers.add(6335); // fwdref is 6285 // // // base class of 6335 -// debugIndexNumbers.add(6341); // fwdref is 6329 +// debugIndexNumbers.add(6341); // fwdref is 6329 } /** * Developmental method for breakpoints. TODO: will delete this from production. - * Set breakpoint on {@code int a = 1;} - * @param recordNumber the record number tha is being processed (set negative to ignore) + * Set breakpoint on {@code #doNothingSetBreakPointHere();} + * @param recordNumber the record number that is being processed (set negative to ignore) *

* 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 @@ -315,8 +321,7 @@ public class PdbResearch { */ static void checkBreak(int recordNumber) { if (debugIndexNumbers.contains(recordNumber)) { - int a = 1; - a = a + 1; + doNothingSetBreakPointHere(); } } @@ -331,16 +336,13 @@ public class PdbResearch { String nn = applier.getMsType().getName(); if ("std::__1::__map_value_compare,std::__1::__value_type,std::__1::basic_string >,std::__1::less,1>".equals( nn)) { - int a = 1; - a = a + 1; + doNothingSetBreakPointHere(); } if ("class std::__1::__iostream_category".equals(nn)) { - int a = 1; - a = a + 1; + doNothingSetBreakPointHere(); } if ("std::__1::__do_message".equals(nn)) { - int a = 1; - a = a + 1; + doNothingSetBreakPointHere(); } //checkBreak(recordNumber); @@ -445,9 +447,10 @@ public class PdbResearch { } else if (applier instanceof ReferenceSymbolApplier) { ReferenceSymbolApplier refSymbolApplier = (ReferenceSymbolApplier) applier; - SymbolGroup refSymbolGroup = refSymbolApplier.getInitializedReferencedSymbolGroup(); + AbstractMsSymbolIterator refIter = + refSymbolApplier.getInitializedReferencedSymbolGroupIterator(); // recursion - childWalkSym(applicator, refSymbolGroup.getModuleNumber(), refSymbolGroup.iterator()); + childWalkSym(applicator, refIter.getModuleNumber(), refIter); } else if (applier instanceof DataSymbolApplier) { DataSymbolApplier dataSymbolApplier = (DataSymbolApplier) applier; @@ -464,19 +467,16 @@ public class PdbResearch { // ConstantSymbolApplier constantSymbolApplier = (ConstantSymbolApplier) applier; // } else { - int a = 1; - a = a + 1; + doNothingSetBreakPointHere(); } return true; } //============================================================================================== static private boolean childWalkType(int moduleNumber, MsTypeApplier applier) { - int b = 1; - b = b + 1; + doNothingSetBreakPointHere(); if (applier instanceof AbstractFunctionTypeApplier) { - int a = 1; - a = a + 1; + doNothingSetBreakPointHere(); } return true; } @@ -861,21 +861,18 @@ public class PdbResearch { p = compType.getMsProperty(); isForwardReference = p.isForwardReference(); if (c == 0 && !isForwardReference) { - int a = 1; - a = a + 1; + doNothingSetBreakPointHere(); // For PDBs that we have looked at, if count is zero // 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 b = 1; - b = b + 1; + doNothingSetBreakPointHere(); } } else if (c != 0 && isForwardReference) { - int a = 1; - a = a + 1; + doNothingSetBreakPointHere(); } // ps = c + (p.isForwardReference() ? "fwdref" : ""); } @@ -916,13 +913,11 @@ public class PdbResearch { // list. So... seems we can trust forward reference and // ignore count. if (compType.getFieldDescriptorListRecordNumber() == RecordNumber.NO_TYPE) { - int a = 1; - a = a + 1; + doNothingSetBreakPointHere(); } } else if (c != 0 && isForwardReference) { - int a = 1; - a = a + 1; + doNothingSetBreakPointHere(); } // ps = c + (p.isForwardReference() ? "fwdref" : ""); } diff --git a/Ghidra/Features/PDB/src/main/java/ghidra/app/util/pdb/pdbapplicator/PdbVbtManager.java b/Ghidra/Features/PDB/src/main/java/ghidra/app/util/pdb/pdbapplicator/PdbVbtManager.java index e0f1367c21..de7ec03920 100644 --- a/Ghidra/Features/PDB/src/main/java/ghidra/app/util/pdb/pdbapplicator/PdbVbtManager.java +++ b/Ghidra/Features/PDB/src/main/java/ghidra/app/util/pdb/pdbapplicator/PdbVbtManager.java @@ -135,8 +135,7 @@ public class PdbVbtManager extends VbtManager { vbtByAddress.put(address, vbt); } if (!(vbt instanceof PdbVirtualBaseTable)) { - int a = 1; - a = a + 1; + // investigate this } return (PdbVirtualBaseTable) vbt; } diff --git a/Ghidra/Features/PDB/src/main/java/ghidra/app/util/pdb/pdbapplicator/ReferenceSymbolApplier.java b/Ghidra/Features/PDB/src/main/java/ghidra/app/util/pdb/pdbapplicator/ReferenceSymbolApplier.java index 279a965aae..3a6335ef2d 100644 --- a/Ghidra/Features/PDB/src/main/java/ghidra/app/util/pdb/pdbapplicator/ReferenceSymbolApplier.java +++ b/Ghidra/Features/PDB/src/main/java/ghidra/app/util/pdb/pdbapplicator/ReferenceSymbolApplier.java @@ -52,15 +52,15 @@ public class ReferenceSymbolApplier extends MsSymbolApplier { @Override void apply() throws CancelledException, PdbException { // Potential recursive call via applicator.procSym(). - AbstractMsSymbolIterator refIter = getInitializedReferencedSymbolGroup().iterator(); + AbstractMsSymbolIterator refIter = getInitializedReferencedSymbolGroupIterator(); applicator.procSym(refIter); } - SymbolGroup getInitializedReferencedSymbolGroup() { + AbstractMsSymbolIterator getInitializedReferencedSymbolGroupIterator() { SymbolGroup refSymbolGroup = getReferencedSymbolGroup(); AbstractMsSymbolIterator refIter = refSymbolGroup.iterator(); refIter.initGetByOffset(getOffsetInReferencedSymbolGroup()); - return refSymbolGroup; + return refIter; } SymbolGroup getReferencedSymbolGroup() { diff --git a/Ghidra/Features/PDB/src/main/java/ghidra/app/util/pdb/pdbapplicator/SeparatedCodeSymbolApplier.java b/Ghidra/Features/PDB/src/main/java/ghidra/app/util/pdb/pdbapplicator/SeparatedCodeSymbolApplier.java index be3772718d..50a7d84978 100644 --- a/Ghidra/Features/PDB/src/main/java/ghidra/app/util/pdb/pdbapplicator/SeparatedCodeSymbolApplier.java +++ b/Ghidra/Features/PDB/src/main/java/ghidra/app/util/pdb/pdbapplicator/SeparatedCodeSymbolApplier.java @@ -129,17 +129,15 @@ public class SeparatedCodeSymbolApplier extends MsSymbolApplier { return (symbolBlockNestingLevel > 0) && iter.hasNext(); } - int endBlock() { + void endBlock() { if (--symbolBlockNestingLevel < 0) { applicator.appendLogMsg("Block Nesting went negative at " + specifiedAddress); } - return symbolBlockNestingLevel; } - private int beginBlock(Address startAddress) { + void beginBlock(Address startAddress) { currentBlockAddress = startAddress; ++symbolBlockNestingLevel; - return symbolBlockNestingLevel; } } diff --git a/Ghidra/Features/PDB/src/main/java/ghidra/app/util/pdb/pdbapplicator/SymbolApplierFactory.java b/Ghidra/Features/PDB/src/main/java/ghidra/app/util/pdb/pdbapplicator/SymbolApplierFactory.java index 672e3d7d89..dc5ee2e7d1 100644 --- a/Ghidra/Features/PDB/src/main/java/ghidra/app/util/pdb/pdbapplicator/SymbolApplierFactory.java +++ b/Ghidra/Features/PDB/src/main/java/ghidra/app/util/pdb/pdbapplicator/SymbolApplierFactory.java @@ -282,12 +282,12 @@ public class SymbolApplierFactory { // case AnnotationMsSymbol.PDB_ID: // symbol = new AnnotationMsSymbol(pdb, reader); // break; -// case GlobalManagedProcedureStMsSymbol.PDB_ID: -// symbol = new GlobalManagedProcedureStMsSymbol(pdb, reader); -// break; -// case LocalManagedProcedureStMsSymbol.PDB_ID: -// symbol = new LocalManagedProcedureStMsSymbol(pdb, reader); -// break; + case GlobalManagedProcedureStMsSymbol.PDB_ID: + applier = new ManagedProcedureSymbolApplier(applicator, iter); + break; + case LocalManagedProcedureStMsSymbol.PDB_ID: + applier = new ManagedProcedureSymbolApplier(applicator, iter); + break; // case Reserved1MsSymbol.PDB_ID: // symbol = new Reserved1MsSymbol(pdb, reader); // break; @@ -455,12 +455,12 @@ public class SymbolApplierFactory { case TokenReferenceToManagedProcedureMsSymbol.PDB_ID: applier = new ReferenceSymbolApplier(applicator, iter); break; -// case GlobalManagedProcedureMsSymbol.PDB_ID: -// symbol = new GlobalManagedProcedureMsSymbol(pdb, reader); -// break; -// case LocalManagedProcedureMsSymbol.PDB_ID: -// symbol = new LocalManagedProcedureMsSymbol(pdb, reader); -// break; + case GlobalManagedProcedureMsSymbol.PDB_ID: + applier = new ManagedProcedureSymbolApplier(applicator, iter); + break; + case LocalManagedProcedureMsSymbol.PDB_ID: + applier = new ManagedProcedureSymbolApplier(applicator, iter); + break; case TrampolineMsSymbol.PDB_ID: applier = new TrampolineSymbolApplier(applicator, iter); break; diff --git a/Ghidra/Features/PDB/src/main/java/ghidra/app/util/pdb/pdbapplicator/SymbolGroup.java b/Ghidra/Features/PDB/src/main/java/ghidra/app/util/pdb/pdbapplicator/SymbolGroup.java index 8d6e47a1a9..cd8b370a6c 100644 --- a/Ghidra/Features/PDB/src/main/java/ghidra/app/util/pdb/pdbapplicator/SymbolGroup.java +++ b/Ghidra/Features/PDB/src/main/java/ghidra/app/util/pdb/pdbapplicator/SymbolGroup.java @@ -150,17 +150,17 @@ public class SymbolGroup { */ class AbstractMsSymbolIterator implements Iterator { - private int currentIndex; + private int nextIndex; private long currentOffset; public AbstractMsSymbolIterator() { - currentIndex = 0; - currentOffset = 0L; + nextIndex = 0; + currentOffset = -1L; } @Override public boolean hasNext() { - if (currentIndex == offsets.size()) { + if (nextIndex == offsets.size()) { return false; } return true; @@ -175,10 +175,10 @@ public class SymbolGroup { * @throws NoSuchElementException if there are no more elements */ public AbstractMsSymbol peek() throws NoSuchElementException { - if (currentIndex == offsets.size()) { + if (nextIndex == offsets.size()) { throw new NoSuchElementException("none left"); } - long temporaryOffset = offsets.get(currentIndex); + long temporaryOffset = offsets.get(nextIndex); AbstractMsSymbol symbol = symbolsByOffset.get(temporaryOffset); if (symbol == null) { throw new NoSuchElementException("No symbol"); @@ -188,10 +188,10 @@ public class SymbolGroup { @Override public AbstractMsSymbol next() { - if (currentIndex == offsets.size()) { + if (nextIndex == offsets.size()) { throw new NoSuchElementException("none left"); } - currentOffset = offsets.get(currentIndex++); + currentOffset = offsets.get(nextIndex++); return symbolsByOffset.get(currentOffset); } @@ -211,7 +211,7 @@ public class SymbolGroup { * @see #hasNext() */ void initGet() { - currentIndex = 0; + nextIndex = 0; } /** @@ -224,7 +224,7 @@ public class SymbolGroup { if (index < 0) { index = 0; } - currentIndex = index; + nextIndex = index; currentOffset = offset; }