GP-2649 - PDB Universal clean-up + fix for CreateFunctionCmd

This commit is contained in:
ghizard 2022-10-04 09:47:36 -04:00
parent e34324ba4e
commit b35f123cae
10 changed files with 26 additions and 37 deletions

View file

@ -22,12 +22,7 @@ import ghidra.framework.model.DomainObject;
import ghidra.program.database.function.OverlappingFunctionException; import ghidra.program.database.function.OverlappingFunctionException;
import ghidra.program.model.address.*; import ghidra.program.model.address.*;
import ghidra.program.model.block.*; import ghidra.program.model.block.*;
import ghidra.program.model.lang.Register;
import ghidra.program.model.lang.RegisterValue;
import ghidra.program.model.listing.*; import ghidra.program.model.listing.*;
import ghidra.program.model.mem.MemoryBlock;
import ghidra.program.model.pcode.PcodeOp;
import ghidra.program.model.pcode.Varnode;
import ghidra.program.model.symbol.*; import ghidra.program.model.symbol.*;
import ghidra.util.Msg; import ghidra.util.Msg;
import ghidra.util.exception.*; import ghidra.util.exception.*;
@ -202,7 +197,8 @@ public class CreateFunctionCmd extends BackgroundCommand {
tmpSource = oldSym.getSource(); tmpSource = oldSym.getSource();
Namespace oldParentNamespace = oldSym.getParentNamespace(); Namespace oldParentNamespace = oldSym.getParentNamespace();
// A function can't have another function as its parent. // A function can't have another function as its parent.
if (oldParentNamespace.getSymbol().getSymbolType() != SymbolType.FUNCTION) { if (oldParentNamespace.getSymbol()
.getSymbolType() != SymbolType.FUNCTION) {
nameSpace = oldParentNamespace; nameSpace = oldParentNamespace;
} }
} }
@ -354,7 +350,7 @@ public class CreateFunctionCmd extends BackgroundCommand {
* @param body - body of function * @param body - body of function
* @param nameSource - source of the name * @param nameSource - source of the name
* @param bodyChangeMap - change map to restore other affected functions bodies if this fails * @param bodyChangeMap - change map to restore other affected functions bodies if this fails
* @param monitor * @param monitor task monitor
* @return * @return
* @throws OverlappingFunctionException * @throws OverlappingFunctionException
* @throws DuplicateNameException * @throws DuplicateNameException
@ -403,7 +399,7 @@ public class CreateFunctionCmd extends BackgroundCommand {
* @param entry - entry point of new function * @param entry - entry point of new function
* @param body - new functions body * @param body - new functions body
* @param bodyChangeMap - map of functions that have their bodies changed by creating this function * @param bodyChangeMap - map of functions that have their bodies changed by creating this function
* @param monitor * @param monitor task monitor
* @return * @return
* @throws CancelledException * @throws CancelledException
* @throws OverlappingFunctionException * @throws OverlappingFunctionException
@ -435,7 +431,7 @@ public class CreateFunctionCmd extends BackgroundCommand {
* *
* @param entry * @param entry
* @param body * @param body
* @param monitor * @param monitor task monitor
* @return the new body, or null if body could not be created and need to abort function creation. * @return the new body, or null if body could not be created and need to abort function creation.
* *
* @throws CancelledException * @throws CancelledException
@ -498,7 +494,7 @@ public class CreateFunctionCmd extends BackgroundCommand {
* *
* @param entry function entry point to check for thunk * @param entry function entry point to check for thunk
* @param body new function body * @param body new function body
* @param monitor * @param monitor task monitor
* @return true if the entry resolved to a thunk * @return true if the entry resolved to a thunk
* *
* @throws OverlappingFunctionException * @throws OverlappingFunctionException
@ -506,7 +502,8 @@ public class CreateFunctionCmd extends BackgroundCommand {
private boolean resolveThunk(Address entry, AddressSetView body, TaskMonitor monitor) private boolean resolveThunk(Address entry, AddressSetView body, TaskMonitor monitor)
throws OverlappingFunctionException { throws OverlappingFunctionException {
Address thunkedAddr = CreateThunkFunctionCmd.getThunkedExternalFunctionAddress(program, entry); Address thunkedAddr =
CreateThunkFunctionCmd.getThunkedExternalFunctionAddress(program, entry);
if (thunkedAddr == null) { if (thunkedAddr == null) {
thunkedAddr = CreateThunkFunctionCmd.getThunkedAddr(program, entry); thunkedAddr = CreateThunkFunctionCmd.getThunkedAddr(program, entry);
} }
@ -591,6 +588,7 @@ public class CreateFunctionCmd extends BackgroundCommand {
/** /**
* Find the function body by following all flows other than a call from the * Find the function body by following all flows other than a call from the
* entry point. * entry point.
* @param monitor task monitor
* @param program the program where the function is being created. * @param program the program where the function is being created.
* @param entry entry point to start tracing flow * @param entry entry point to start tracing flow
* *
@ -650,6 +648,7 @@ public class CreateFunctionCmd extends BackgroundCommand {
* @param monitor task monitor * @param monitor task monitor
* @return true if successful, false if cancelled or unable to fixup function or * @return true if successful, false if cancelled or unable to fixup function or
* no function found containing the start address of the indicated instruction * no function found containing the start address of the indicated instruction
* @throws CancelledException if the function fixup is cancelled.
*/ */
public static boolean fixupFunctionBody(Program program, Instruction start_inst, public static boolean fixupFunctionBody(Program program, Instruction start_inst,
TaskMonitor monitor) throws CancelledException { TaskMonitor monitor) throws CancelledException {
@ -680,7 +679,8 @@ public class CreateFunctionCmd extends BackgroundCommand {
AddressSetView newBody = getFunctionBody(program, entry, false, monitor); AddressSetView newBody = getFunctionBody(program, entry, false, monitor);
// function could now be a thunk, since someone is calling this because of a potential body flow change // function could now be a thunk, since someone is calling this because of a potential body flow change
if (!func.isThunk() && resolveThunk(program, entry, newBody, monitor)) { if (func.getSignatureSource() == SourceType.DEFAULT && !func.isThunk() &&
resolveThunk(program, entry, newBody, monitor)) {
// function flow might have changed, and could now be a thunk, without the body changing. // function flow might have changed, and could now be a thunk, without the body changing.
// don't worry about it below, because if there is an overlapping body, something strange // don't worry about it below, because if there is an overlapping body, something strange
// going on, and the function should still be a thunk // going on, and the function should still be a thunk

View file

@ -339,6 +339,7 @@ public class Module {
pdb.checkCanceled(); pdb.checkCanceled();
AbstractMsSymbol symbol = symbolIterator.next(); AbstractMsSymbol symbol = symbolIterator.next();
writer.append(symbol.toString()); writer.append(symbol.toString());
writer.append("\n");
} }
writer.write("End Symbols-------------------------------------------------\n"); writer.write("End Symbols-------------------------------------------------\n");
} }

View file

@ -118,7 +118,7 @@ public abstract class TypeProgramInterface implements TPI {
/** /**
* Retrieves the {@link AbstractMsType} record indicated by the recordNumber. The record must * Retrieves the {@link AbstractMsType} record indicated by the recordNumber. The record must
* already have been parsed and inserted into the list * already have been parsed and inserted into the list
* @param recordNumber Rrcord number to look up * @param recordNumber record number to look up
* @return {@link AbstractMsType} pertaining to the record number * @return {@link AbstractMsType} pertaining to the record number
*/ */
@Override @Override

View file

@ -257,7 +257,7 @@ public abstract class AbstractCompile2MsSymbol extends AbstractMsSymbol {
builder.append( builder.append(
"\n Compiled for edit and continue: " + (compiledForEditAndContinue ? "yes" : "no")); "\n Compiled for edit and continue: " + (compiledForEditAndContinue ? "yes" : "no"));
builder.append( builder.append(
"\n Compiled withoug debugging info: " + (notCompiledWithDebugInfo ? "yes" : "no")); "\n Compiled without debugging info: " + (notCompiledWithDebugInfo ? "yes" : "no"));
builder.append( builder.append(
"\n Compiled with LTCG: " + (compiledWithLinkTimeCodeGeneration ? "yes" : "no")); "\n Compiled with LTCG: " + (compiledWithLinkTimeCodeGeneration ? "yes" : "no"));
builder.append( builder.append(

View file

@ -287,7 +287,7 @@ public class Compile3MsSymbol extends AbstractMsSymbol {
builder.append( builder.append(
"\n Compiled for edit and continue: " + (compiledForEditAndContinue ? "yes" : "no")); "\n Compiled for edit and continue: " + (compiledForEditAndContinue ? "yes" : "no"));
builder.append( builder.append(
"\n Compiled withoug debugging info: " + (notCompiledWithDebugInfo ? "yes" : "no")); "\n Compiled without debugging info: " + (notCompiledWithDebugInfo ? "yes" : "no"));
builder.append( builder.append(
"\n Compiled with LTCG: " + (compiledWithLinkTimeCodeGeneration ? "yes" : "no")); "\n Compiled with LTCG: " + (compiledWithLinkTimeCodeGeneration ? "yes" : "no"));
builder.append( builder.append(

View file

@ -252,14 +252,8 @@ public class FunctionSymbolApplier extends MsSymbolApplier {
} }
private boolean applyFunction(TaskMonitor monitor) { private boolean applyFunction(TaskMonitor monitor) {
Listing listing = applicator.getProgram().getListing();
applicator.createSymbol(address, getName(), true); applicator.createSymbol(address, getName(), true);
function = createFunction(monitor);
function = listing.getFunctionAt(address);
if (function == null) {
function = createFunction(monitor);
}
if (function == null) { if (function == null) {
return false; return false;
} }

View file

@ -142,14 +142,8 @@ public class LabelSymbolApplier extends MsSymbolApplier {
} }
private boolean applyFunction(Address address, String name, TaskMonitor monitor) { private boolean applyFunction(Address address, String name, TaskMonitor monitor) {
Listing listing = applicator.getProgram().getListing();
applicator.createSymbol(address, name, true); applicator.createSymbol(address, name, true);
function = createFunction(address, monitor);
function = listing.getFunctionAt(address);
if (function == null) {
function = createFunction(address, monitor);
}
if (function == null) { if (function == null) {
return false; return false;
} }

View file

@ -158,6 +158,8 @@ class LoadPdbTask extends Task {
return false; return false;
} }
// We need to kick off any byte analyzers (like getting import symbols), as they typically
// won't get kicked off by our loading of the PDB.
private void scheduleAdditionalAnalysis() { private void scheduleAdditionalAnalysis() {
AddressSetView addrs = program.getMemory(); AddressSetView addrs = program.getMemory();
@ -169,15 +171,13 @@ class LoadPdbTask extends Task {
scheduleDemangler(manager, analysisProperties, addrs); scheduleDemangler(manager, analysisProperties, addrs);
} }
// DemanglerAnalyzer is a byte analyzer (like getting import symbols), so it won't get
// kicked off by our laying down symbols.
private void scheduleDemangler(AutoAnalysisManager manager, Options analysisProperties, private void scheduleDemangler(AutoAnalysisManager manager, Options analysisProperties,
AddressSetView addrs) { AddressSetView addrs) {
MicrosoftDemanglerAnalyzer demanglerAnalyzer = new MicrosoftDemanglerAnalyzer(); MicrosoftDemanglerAnalyzer demanglerAnalyzer = new MicrosoftDemanglerAnalyzer();
String analyzerName = demanglerAnalyzer.getName(); String analyzerName = demanglerAnalyzer.getName();
String valueAsString = analysisProperties.getValueAsString(analyzerName); String valueAsString = analysisProperties.getValueAsString(analyzerName);
// Do not demangle if the demangler analyzer is turned off // Only schedule analyzer if enabled
if (!Boolean.parseBoolean(valueAsString)) { if (!Boolean.parseBoolean(valueAsString)) {
return; return;
} }

View file

@ -55,7 +55,7 @@ public class DummyPdb700 extends Pdb700 {
} }
/** /**
* Set @code true} to make existing debug information available; when set false, * Set {@code true} to make existing debug information available; when set false,
* {@link #getDebugInfo()} returns null (as though it does not exist) * {@link #getDebugInfo()} returns null (as though it does not exist)
* @param setAvailable {@code true} to return actual value; @code false} to have it return null * @param setAvailable {@code true} to return actual value; @code false} to have it return null
*/ */

View file

@ -19,14 +19,14 @@ import java.io.IOException;
import javax.help.UnsupportedOperationException; import javax.help.UnsupportedOperationException;
import ghidra.app.util.bin.format.pdb2.pdbreader.*; import ghidra.app.util.bin.format.pdb2.pdbreader.PdbByteReader;
import ghidra.app.util.bin.format.pdb2.pdbreader.PdbException;
import ghidra.util.exception.CancelledException; import ghidra.util.exception.CancelledException;
import ghidra.util.task.TaskMonitor; import ghidra.util.task.TaskMonitor;
/** /**
* This class is an extension of {@link Pdb700}, based on {@link AbstractPdb}, whose sole purpose * This class is an extension of {@link Msf}, and has the sole purpose of stubbing the Msf for
* is to allow for testing of internal components of {@link AbstractPdb} classes. It is not * testing of internal components of PDB classes.
* part of the production PDB Reader.
*/ */
public class StubMsf implements Msf { public class StubMsf implements Msf {