mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2024-11-14 16:12:14 +00:00
Merge remote-tracking branch 'origin/GP-3604_PDB_Remove_DisassembleCommand--SQUASHED'
This commit is contained in:
commit
c3d10529f0
@ -22,9 +22,10 @@ import org.apache.commons.io.FilenameUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import ghidra.app.cmd.comments.SetCommentCmd;
|
||||
import ghidra.app.cmd.disassemble.DisassembleCommand;
|
||||
import ghidra.app.cmd.function.CreateFunctionCmd;
|
||||
import ghidra.app.cmd.label.SetLabelPrimaryCmd;
|
||||
import ghidra.app.util.NamespaceUtils;
|
||||
import ghidra.app.util.SymbolPath;
|
||||
import ghidra.app.util.*;
|
||||
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.*;
|
||||
@ -37,7 +38,9 @@ import ghidra.framework.options.Options;
|
||||
import ghidra.graph.*;
|
||||
import ghidra.graph.algo.GraphNavigator;
|
||||
import ghidra.graph.jung.JungDirectedGraph;
|
||||
import ghidra.program.disassemble.DisassemblerContextImpl;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.address.AddressSet;
|
||||
import ghidra.program.model.data.*;
|
||||
import ghidra.program.model.lang.Register;
|
||||
import ghidra.program.model.listing.*;
|
||||
@ -163,6 +166,11 @@ public class DefaultPdbApplicator implements PdbApplicator {
|
||||
private Map<String, Set<RecordNumber>> recordNumbersByFileName;
|
||||
private Map<Integer, Set<RecordNumber>> recordNumbersByModuleNumber;
|
||||
|
||||
//==============================================================================================
|
||||
// Addresses of locations of functions for disassembly/function-creation.
|
||||
AddressSet disassembleAddresses;
|
||||
List<DeferrableFunctionSymbolApplier> deferredFunctionWorkAppliers;
|
||||
|
||||
//==============================================================================================
|
||||
public DefaultPdbApplicator(AbstractPdb pdb) {
|
||||
Objects.requireNonNull(pdb, "pdb cannot be null");
|
||||
@ -213,6 +221,8 @@ public class DefaultPdbApplicator implements PdbApplicator {
|
||||
}
|
||||
|
||||
if (program != null) {
|
||||
doDeferredProgramProcessing();
|
||||
// Mark PDB analysis as complete.
|
||||
Options options = program.getOptions(Program.PROGRAM_INFO);
|
||||
options.setBoolean(PdbParserConstants.PDB_LOADED, true);
|
||||
}
|
||||
@ -224,6 +234,57 @@ public class DefaultPdbApplicator implements PdbApplicator {
|
||||
Msg.info(this, "PDB Terminated Normally");
|
||||
}
|
||||
|
||||
//==============================================================================================
|
||||
private void doDeferredProgramProcessing() throws CancelledException {
|
||||
disassembleFunctions();
|
||||
doDeferredFunctionProcessing();
|
||||
}
|
||||
|
||||
//==============================================================================================
|
||||
/**
|
||||
* Set the context for each function, disassemble them, and then do fix-ups
|
||||
*/
|
||||
private void disassembleFunctions() throws CancelledException {
|
||||
|
||||
Listing listing = program.getListing();
|
||||
DisassemblerContextImpl seedContext =
|
||||
new DisassemblerContextImpl(program.getProgramContext());
|
||||
AddressSet revisedSet = new AddressSet();
|
||||
for (Address address : disassembleAddresses.getAddresses(true)) {
|
||||
cancelOnlyWrappingMonitor.checkCancelled();
|
||||
address = PseudoDisassembler.setTargetContextForDisassembly(seedContext, address);
|
||||
Function myFunction = listing.getFunctionAt(address);
|
||||
// If no function or not a full function, add it to set for disassembly.
|
||||
if (myFunction == null || myFunction.getBody().getNumAddresses() <= 1) {
|
||||
revisedSet.add(address);
|
||||
}
|
||||
}
|
||||
// Do disassembly and ensure functions are created appropriately.
|
||||
DisassembleCommand cmd = new DisassembleCommand(revisedSet, null, true);
|
||||
cmd.setSeedContext(seedContext);
|
||||
cmd.applyTo(program, cancelOnlyWrappingMonitor);
|
||||
|
||||
for (Address address : revisedSet.getAddresses(true)) {
|
||||
cancelOnlyWrappingMonitor.checkCancelled();
|
||||
Function function = listing.getFunctionAt(address);
|
||||
if (function != null) {
|
||||
CreateFunctionCmd.fixupFunctionBody(program, function, cancelOnlyWrappingMonitor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//==============================================================================================
|
||||
/**
|
||||
* Do work, such as create parameters or local variables and scopes
|
||||
* @throws CancelledException upon user cancellation
|
||||
*/
|
||||
private void doDeferredFunctionProcessing() throws CancelledException {
|
||||
for (DeferrableFunctionSymbolApplier applier : deferredFunctionWorkAppliers) {
|
||||
cancelOnlyWrappingMonitor.checkCancelled();
|
||||
applier.doDeferredProcessing();
|
||||
}
|
||||
}
|
||||
|
||||
//==============================================================================================
|
||||
private void processTypes() throws CancelledException, PdbException {
|
||||
TaskMonitor monitor = getMonitor();
|
||||
@ -359,6 +420,8 @@ public class DefaultPdbApplicator implements PdbApplicator {
|
||||
symbolApplierParser = new SymbolApplierFactory(this);
|
||||
|
||||
if (program != null) {
|
||||
disassembleAddresses = new AddressSet();
|
||||
deferredFunctionWorkAppliers = new ArrayList<>();
|
||||
// Currently, this must happen after symbolGroups are created.
|
||||
PdbVbtManager pdbVbtManager = new PdbVbtManager(this);
|
||||
//pdbVbtManager.CreateVirtualBaseTables(); // Depends on symbolGroups
|
||||
@ -849,6 +912,42 @@ public class DefaultPdbApplicator implements PdbApplicator {
|
||||
//==============================================================================================
|
||||
//==============================================================================================
|
||||
//==============================================================================================
|
||||
//==============================================================================================
|
||||
Function getExistingOrCreateOneByteFunction(Address address) {
|
||||
if (program == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Get normalized address for function creation
|
||||
Address normalizedAddress =
|
||||
PseudoDisassembler.getNormalizedDisassemblyAddress(program, address);
|
||||
|
||||
// Does function already exist?
|
||||
Function myFunction = program.getListing().getFunctionAt(normalizedAddress);
|
||||
if (myFunction != null) {
|
||||
return myFunction;
|
||||
}
|
||||
|
||||
CreateFunctionCmd funCmd = new CreateFunctionCmd(null, normalizedAddress,
|
||||
new AddressSet(normalizedAddress, normalizedAddress),
|
||||
SourceType.DEFAULT);
|
||||
if (!funCmd.applyTo(program, cancelOnlyWrappingMonitor)) {
|
||||
appendLogMsg("Failed to apply function at address " + address.toString() +
|
||||
"; attempting to use possible existing function");
|
||||
return program.getListing().getFunctionAt(normalizedAddress);
|
||||
}
|
||||
myFunction = funCmd.getFunction();
|
||||
|
||||
return myFunction;
|
||||
}
|
||||
|
||||
//==============================================================================================
|
||||
void scheduleDeferredFunctionWork(DeferrableFunctionSymbolApplier applier) {
|
||||
// Not using normalized address is OK, as we should have already set the context and
|
||||
// used the normalized address when creating the one-byte function
|
||||
disassembleAddresses.add(applier.getAddress());
|
||||
deferredFunctionWorkAppliers.add(applier);
|
||||
}
|
||||
|
||||
//==============================================================================================
|
||||
// SymbolGroup-related methods.
|
||||
|
@ -0,0 +1,41 @@
|
||||
/* ###
|
||||
* 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 ghidra.program.model.address.Address;
|
||||
|
||||
/**
|
||||
* Interface class for MsSymbolApplier that has deferrable function work.
|
||||
*/
|
||||
interface DeferrableFunctionSymbolApplier {
|
||||
|
||||
/**
|
||||
* Returns entry address of code/function that needs disassembled; this is the original,
|
||||
* non-normalized address (e.g., odd if Thumb)
|
||||
* @return the address
|
||||
*/
|
||||
Address getAddress();
|
||||
|
||||
/**
|
||||
* Deferred work for the MsSymbolApplier that can only be applied after all functions
|
||||
* have been created and disassembled. Examples would be setting local variables and
|
||||
* parameters
|
||||
*/
|
||||
default void doDeferredProcessing() {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
}
|
@ -17,8 +17,8 @@ package ghidra.app.util.pdb.pdbapplicator;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import ghidra.app.cmd.disassemble.DisassembleCommand;
|
||||
import ghidra.app.cmd.function.*;
|
||||
import ghidra.app.cmd.function.ApplyFunctionSignatureCmd;
|
||||
import ghidra.app.cmd.function.CallDepthChangeInfo;
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.PdbException;
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.RecordNumber;
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.symbol.*;
|
||||
@ -37,7 +37,8 @@ import ghidra.util.task.TaskMonitor;
|
||||
/**
|
||||
* Applier for {@link AbstractProcedureStartMsSymbol} and {@link AbstractThunkMsSymbol} symbols.
|
||||
*/
|
||||
public class FunctionSymbolApplier extends MsSymbolApplier {
|
||||
public class FunctionSymbolApplier extends MsSymbolApplier
|
||||
implements DeferrableFunctionSymbolApplier {
|
||||
|
||||
private static final String BLOCK_INDENT = " ";
|
||||
|
||||
@ -134,6 +135,16 @@ public class FunctionSymbolApplier extends MsSymbolApplier {
|
||||
}
|
||||
}
|
||||
|
||||
long getLength() {
|
||||
if (procedureSymbol != null) {
|
||||
return procedureSymbol.getProcedureLength();
|
||||
}
|
||||
else if (thunkSymbol != null) {
|
||||
return thunkSymbol.getLength();
|
||||
}
|
||||
throw new AssertException("Unexpected Symbol type");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link Function} for this applier.
|
||||
* @return the Function
|
||||
@ -252,15 +263,16 @@ public class FunctionSymbolApplier extends MsSymbolApplier {
|
||||
}
|
||||
|
||||
private boolean applyFunction(TaskMonitor monitor) {
|
||||
function = createFunction(monitor);
|
||||
function = applicator.getExistingOrCreateOneByteFunction(address);
|
||||
if (function == null) {
|
||||
return false;
|
||||
}
|
||||
applicator.scheduleDeferredFunctionWork(this);
|
||||
|
||||
boolean succeededSetFunctionSignature = false;
|
||||
if (thunkSymbol == null) {
|
||||
function.setThunkedFunction(null);
|
||||
if (function.getSignatureSource().isLowerPriorityThan(SourceType.IMPORTED)) {
|
||||
function.setThunkedFunction(null);
|
||||
succeededSetFunctionSignature = setFunctionDefinition(monitor);
|
||||
function.setNoReturn(isNonReturning);
|
||||
}
|
||||
@ -274,28 +286,6 @@ public class FunctionSymbolApplier extends MsSymbolApplier {
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns true only if we set a function signature
|
||||
* @param monitor monitor
|
||||
@ -352,21 +342,6 @@ public class FunctionSymbolApplier extends MsSymbolApplier {
|
||||
return true;
|
||||
}
|
||||
|
||||
private Function createFunctionCommand(TaskMonitor monitor) {
|
||||
CreateFunctionCmd funCmd = new CreateFunctionCmd(address);
|
||||
if (!funCmd.applyTo(applicator.getProgram(), monitor)) {
|
||||
funCmd = new CreateFunctionCmd(null, address, new AddressSet(address, address),
|
||||
SourceType.DEFAULT);
|
||||
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();
|
||||
}
|
||||
@ -500,4 +475,16 @@ public class FunctionSymbolApplier extends MsSymbolApplier {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doDeferredProcessing() {
|
||||
// TODO:
|
||||
// Try to processes parameters, locals, scopes if applicable.
|
||||
}
|
||||
|
||||
@Override
|
||||
public Address getAddress() {
|
||||
return address;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -17,8 +17,6 @@ package ghidra.app.util.pdb.pdbapplicator;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
|
||||
import ghidra.app.cmd.disassemble.DisassembleCommand;
|
||||
import ghidra.app.cmd.function.CreateFunctionCmd;
|
||||
import ghidra.app.util.NamespaceUtils;
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.PdbException;
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.symbol.AbstractLabelMsSymbol;
|
||||
@ -26,16 +24,15 @@ import ghidra.app.util.bin.format.pdb2.pdbreader.symbol.AbstractMsSymbol;
|
||||
import ghidra.app.util.pdb.pdbapplicator.SymbolGroup.AbstractMsSymbolIterator;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.listing.Function;
|
||||
import ghidra.program.model.listing.Instruction;
|
||||
import ghidra.program.model.symbol.SourceType;
|
||||
import ghidra.util.Msg;
|
||||
import ghidra.util.exception.*;
|
||||
import ghidra.util.exception.AssertException;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
/**
|
||||
* Applier for {@link AbstractLabelMsSymbol} symbols.
|
||||
*/
|
||||
public class LabelSymbolApplier extends MsSymbolApplier {
|
||||
public class LabelSymbolApplier extends MsSymbolApplier implements DeferrableFunctionSymbolApplier {
|
||||
|
||||
private AbstractLabelMsSymbol symbol;
|
||||
private Function function = null;
|
||||
@ -162,10 +159,11 @@ public class LabelSymbolApplier extends MsSymbolApplier {
|
||||
|
||||
private boolean applyFunction(Address address, String name, TaskMonitor monitor) {
|
||||
applicator.createSymbol(address, name, true);
|
||||
function = createFunction(address, monitor);
|
||||
function = applicator.getExistingOrCreateOneByteFunction(address);
|
||||
if (function == null) {
|
||||
return false;
|
||||
}
|
||||
applicator.scheduleDeferredFunctionWork(this);
|
||||
|
||||
if (!function.isThunk() &&
|
||||
function.getSignatureSource().isLowerPriorityThan(SourceType.IMPORTED)) {
|
||||
@ -176,48 +174,12 @@ public class LabelSymbolApplier extends MsSymbolApplier {
|
||||
function.setNoReturn(isNonReturning());
|
||||
// We have seen no examples of custom calling convention flag being set.
|
||||
if (hasCustomCallingConvention()) {
|
||||
try {
|
||||
function.setCallingConvention("unknown");
|
||||
}
|
||||
catch (InvalidInputException e) {
|
||||
Msg.warn(this,
|
||||
"PDB: Could not set \"unknown\" calling convention for label: " + name);
|
||||
}
|
||||
// For now: do nothing... the convention is unknown by default.
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private Function createFunction(Address address, TaskMonitor monitor) {
|
||||
|
||||
// Check for existing function.
|
||||
Function myFunction = applicator.getProgram().getListing().getFunctionAt(address);
|
||||
if (myFunction != null) {
|
||||
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(address, monitor);
|
||||
|
||||
return myFunction;
|
||||
}
|
||||
|
||||
private Function createFunctionCommand(Address address, 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();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns label to apply or null if label excluded
|
||||
* @return label to process or null
|
||||
@ -235,4 +197,9 @@ public class LabelSymbolApplier extends MsSymbolApplier {
|
||||
}
|
||||
return label;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Address getAddress() {
|
||||
return applicator.getAddress(symbol);
|
||||
}
|
||||
}
|
||||
|
@ -17,9 +17,7 @@ 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;
|
||||
@ -50,7 +48,8 @@ import ghidra.util.task.TaskMonitor;
|
||||
/**
|
||||
* Applier for {@link AbstractManagedProcedureMsSymbol} symbols.
|
||||
*/
|
||||
public class ManagedProcedureSymbolApplier extends MsSymbolApplier {
|
||||
public class ManagedProcedureSymbolApplier extends MsSymbolApplier
|
||||
implements DeferrableFunctionSymbolApplier {
|
||||
|
||||
private static final String BLOCK_INDENT = " ";
|
||||
|
||||
@ -242,17 +241,14 @@ public class ManagedProcedureSymbolApplier extends MsSymbolApplier {
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
function = applicator.getExistingOrCreateOneByteFunction(address);
|
||||
if (function == null) {
|
||||
return false;
|
||||
}
|
||||
applicator.scheduleDeferredFunctionWork(this);
|
||||
|
||||
if (!function.isThunk() &&
|
||||
function.getSignatureSource().isLowerPriorityThan(SourceType.IMPORTED)) {
|
||||
@ -263,28 +259,6 @@ public class ManagedProcedureSymbolApplier extends MsSymbolApplier {
|
||||
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?
|
||||
@ -364,16 +338,6 @@ public class ManagedProcedureSymbolApplier extends MsSymbolApplier {
|
||||
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();
|
||||
}
|
||||
@ -507,4 +471,15 @@ public class ManagedProcedureSymbolApplier extends MsSymbolApplier {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doDeferredProcessing() {
|
||||
// TODO:
|
||||
// Try to processes parameters, locals, scopes if applicable.
|
||||
}
|
||||
|
||||
@Override
|
||||
public Address getAddress() {
|
||||
return address;
|
||||
}
|
||||
}
|
||||
|
@ -15,14 +15,11 @@
|
||||
*/
|
||||
package ghidra.app.util.pdb.pdbapplicator;
|
||||
|
||||
import ghidra.app.cmd.disassemble.DisassembleCommand;
|
||||
import ghidra.app.cmd.function.CreateFunctionCmd;
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.PdbException;
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.symbol.AbstractMsSymbol;
|
||||
import ghidra.app.util.bin.format.pdb2.pdbreader.symbol.TrampolineMsSymbol;
|
||||
import ghidra.app.util.pdb.pdbapplicator.SymbolGroup.AbstractMsSymbolIterator;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.address.AddressSet;
|
||||
import ghidra.program.model.listing.Function;
|
||||
import ghidra.util.exception.AssertException;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
@ -30,9 +27,11 @@ import ghidra.util.exception.CancelledException;
|
||||
/**
|
||||
* Applier for {@link TrampolineMsSymbol} symbols.
|
||||
*/
|
||||
public class TrampolineSymbolApplier extends MsSymbolApplier {
|
||||
public class TrampolineSymbolApplier extends MsSymbolApplier
|
||||
implements DeferrableFunctionSymbolApplier {
|
||||
|
||||
private TrampolineMsSymbol symbol;
|
||||
private Address address;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
@ -47,6 +46,7 @@ public class TrampolineSymbolApplier extends MsSymbolApplier {
|
||||
"Invalid symbol type: " + abstractSymbol.getClass().getSimpleName());
|
||||
}
|
||||
symbol = (TrampolineMsSymbol) abstractSymbol;
|
||||
address = applicator.getAddress(symbol);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -57,21 +57,22 @@ public class TrampolineSymbolApplier extends MsSymbolApplier {
|
||||
@Override
|
||||
void apply() throws CancelledException, PdbException {
|
||||
// We know the size of this trampoline, so use it to restrict the disassembly.
|
||||
Address symbolAddress = applicator.getAddress(symbol);
|
||||
Address targetAddress =
|
||||
applicator.getAddress(symbol.getSegmentTarget(), symbol.getOffsetTarget());
|
||||
|
||||
Function target = null;
|
||||
Function thunk = null;
|
||||
if (!applicator.isInvalidAddress(targetAddress, "thunk target")) {
|
||||
target = createNewFunction(targetAddress, 1);
|
||||
target = applicator.getExistingOrCreateOneByteFunction(targetAddress);
|
||||
}
|
||||
if (!applicator.isInvalidAddress(symbolAddress, "thunk symbol")) {
|
||||
thunk = createNewFunction(symbolAddress, symbol.getSizeOfThunk());
|
||||
if (!applicator.isInvalidAddress(address, "thunk symbol")) {
|
||||
thunk = applicator.getExistingOrCreateOneByteFunction(address);
|
||||
}
|
||||
if (target != null && thunk != null) {
|
||||
thunk.setThunkedFunction(target);
|
||||
}
|
||||
applicator.scheduleDeferredFunctionWork(this);
|
||||
|
||||
// int thunkModule = findModuleNumberBySectionOffsetContribution(symbol.getSectionThunk(),
|
||||
// symbol.getOffsetThunk());
|
||||
// int targetModule = findModuleNumberBySectionOffsetContribution(symbol.getSectionTarget(),
|
||||
@ -79,31 +80,14 @@ public class TrampolineSymbolApplier extends MsSymbolApplier {
|
||||
|
||||
}
|
||||
|
||||
// TODO? If we wanted to be able to apply this symbol to a different address, we should
|
||||
@Override
|
||||
public Address getAddress() {
|
||||
return address;
|
||||
}
|
||||
|
||||
// TODO? If we wanted to be able to apply this symbol to a different address, we should
|
||||
// review code in FunctionSymbolApplier. Note, however, that there are two addresses
|
||||
// that need to be dealt with here, and each could have a different address with a different
|
||||
// delta from the specified address.
|
||||
|
||||
private Function createNewFunction(Address startAddress, long size) {
|
||||
|
||||
AddressSet addressSet = new AddressSet(startAddress, startAddress.add(size));
|
||||
|
||||
if (applicator.getProgram().getListing().getInstructionAt(startAddress) == null) {
|
||||
DisassembleCommand cmd = new DisassembleCommand(addressSet, null, true); // TODO: false?
|
||||
cmd.applyTo(applicator.getProgram(), applicator.getCancelOnlyWrappingMonitor());
|
||||
}
|
||||
|
||||
// Only create function if it does not already exist.
|
||||
Function function = applicator.getProgram().getListing().getFunctionAt(startAddress);
|
||||
if (function != null) {
|
||||
return function;
|
||||
}
|
||||
CreateFunctionCmd funCmd = new CreateFunctionCmd(startAddress);
|
||||
if (!funCmd.applyTo(applicator.getProgram(), applicator.getCancelOnlyWrappingMonitor())) {
|
||||
applicator.appendLogMsg("Failed to apply function at address " +
|
||||
startAddress.toString() + "; attempting to use possible existing function");
|
||||
}
|
||||
return funCmd.getFunction();
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user