mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 19:42:36 +02:00
Fixed tests failing to recent Version Tracking updates. Added a
priority to Version Tracking address correlators.
This commit is contained in:
parent
220d6d9f58
commit
0fbd23653d
24 changed files with 488 additions and 293 deletions
|
@ -44,7 +44,6 @@ public class AnalysisPriority {
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defines a full format analysis as the first priority for automatic analysis.
|
* Defines a full format analysis as the first priority for automatic analysis.
|
||||||
* These are the first analyzers that will run after import.
|
* These are the first analyzers that will run after import.
|
||||||
|
@ -78,7 +77,7 @@ public class AnalysisPriority {
|
||||||
* instructions <code>AnalyzerType.INSTRUCTIONS</code>. It is also useful for
|
* instructions <code>AnalyzerType.INSTRUCTIONS</code>. It is also useful for
|
||||||
* those analyzers that depend on code, but want to analyze flow, such as non-returning
|
* those analyzers that depend on code, but want to analyze flow, such as non-returning
|
||||||
* functions, that should happen before functions are widely laid down. If
|
* functions, that should happen before functions are widely laid down. If
|
||||||
* bad flow is not fixed at an early priority, switch stmt recovery, function
|
* bad flow is not fixed at an early priority, switch statement recovery, function
|
||||||
* boundaries, etc... may need to be redone and bad stuff cleaned up.
|
* boundaries, etc... may need to be redone and bad stuff cleaned up.
|
||||||
*/
|
*/
|
||||||
public final static AnalysisPriority CODE_ANALYSIS = DISASSEMBLY.getNext("CODE");
|
public final static AnalysisPriority CODE_ANALYSIS = DISASSEMBLY.getNext("CODE");
|
||||||
|
@ -114,8 +113,8 @@ public class AnalysisPriority {
|
||||||
DATA_ANALYSIS.getNext("FUNCTION ID");
|
DATA_ANALYSIS.getNext("FUNCTION ID");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defines data type propogation as the ninth priority for automatic analysis.
|
* Defines data type propagation as the ninth priority for automatic analysis.
|
||||||
* Data type propogation analysis should hapen as late as possible so that all basic code
|
* Data type propagation analysis should happen as late as possible so that all basic code
|
||||||
* recovery, reference analysis, etc... has taken place.
|
* recovery, reference analysis, etc... has taken place.
|
||||||
*/
|
*/
|
||||||
public final static AnalysisPriority DATA_TYPE_PROPOGATION =
|
public final static AnalysisPriority DATA_TYPE_PROPOGATION =
|
||||||
|
@ -136,6 +135,7 @@ public class AnalysisPriority {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct a new priority object.
|
* Construct a new priority object.
|
||||||
|
* @param name the name
|
||||||
* @param priority priority to use
|
* @param priority priority to use
|
||||||
*/
|
*/
|
||||||
public AnalysisPriority(String name, int priority) {
|
public AnalysisPriority(String name, int priority) {
|
||||||
|
@ -145,6 +145,7 @@ public class AnalysisPriority {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the priority specified for this analysis priority.
|
* Return the priority specified for this analysis priority.
|
||||||
|
* @return the priority specified for this analysis priority.
|
||||||
*/
|
*/
|
||||||
public int priority() {
|
public int priority() {
|
||||||
return priority;
|
return priority;
|
||||||
|
@ -160,7 +161,7 @@ public class AnalysisPriority {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a piority that is a little lower than this one.
|
* Get a priority that is a little lower than this one.
|
||||||
*
|
*
|
||||||
* @return a lower priority
|
* @return a lower priority
|
||||||
*/
|
*/
|
||||||
|
@ -170,6 +171,7 @@ public class AnalysisPriority {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return first gross priority.
|
* Return first gross priority.
|
||||||
|
* @param name the name
|
||||||
* @return first gross priority
|
* @return first gross priority
|
||||||
*/
|
*/
|
||||||
public static AnalysisPriority getInitial(String name) {
|
public static AnalysisPriority getInitial(String name) {
|
||||||
|
@ -178,6 +180,7 @@ public class AnalysisPriority {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the next gross priority.
|
* Get the next gross priority.
|
||||||
|
* @param nextName the next name
|
||||||
* @return return next gross priority
|
* @return return next gross priority
|
||||||
*/
|
*/
|
||||||
public AnalysisPriority getNext(String nextName) {
|
public AnalysisPriority getNext(String nextName) {
|
||||||
|
|
|
@ -31,6 +31,9 @@ import ghidra.util.exception.CancelledException;
|
||||||
import ghidra.util.task.TaskMonitor;
|
import ghidra.util.task.TaskMonitor;
|
||||||
|
|
||||||
public class CodeCompareAddressCorrelation implements AddressCorrelation {
|
public class CodeCompareAddressCorrelation implements AddressCorrelation {
|
||||||
|
|
||||||
|
public static final String NAME = "CodeCompareAddressCorrelator";
|
||||||
|
|
||||||
static enum CorrelationKind {
|
static enum CorrelationKind {
|
||||||
CODE_COMPARE, LCS, PARAMETERS;
|
CODE_COMPARE, LCS, PARAMETERS;
|
||||||
}
|
}
|
||||||
|
@ -65,15 +68,16 @@ public class CodeCompareAddressCorrelation implements AddressCorrelation {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AddressRange getCorrelatedDestinationRange(Address sourceAddress, TaskMonitor monitor)
|
public AddressCorrelationRange getCorrelatedDestinationRange(Address sourceAddress,
|
||||||
throws CancelledException {
|
TaskMonitor monitor) throws CancelledException {
|
||||||
initialize(monitor);
|
initialize(monitor);
|
||||||
|
|
||||||
CorrelationContainer container = cachedForwardAddressMap.get(sourceAddress);
|
CorrelationContainer container = cachedForwardAddressMap.get(sourceAddress);
|
||||||
if (container == null) {
|
if (container == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return container.range;
|
|
||||||
|
return new AddressCorrelationRange(container.range, getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final Comparator<CodeUnit> CUCOMPARATOR = new Comparator<CodeUnit>() {
|
private static final Comparator<CodeUnit> CUCOMPARATOR = new Comparator<CodeUnit>() {
|
||||||
|
@ -446,6 +450,6 @@ public class CodeCompareAddressCorrelation implements AddressCorrelation {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return "CodeCompareAddressCorrelator";
|
return NAME;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,9 +20,9 @@ import ghidra.framework.options.ToolOptions;
|
||||||
import ghidra.program.model.lang.Language;
|
import ghidra.program.model.lang.Language;
|
||||||
import ghidra.program.model.listing.*;
|
import ghidra.program.model.listing.*;
|
||||||
import ghidra.program.util.AddressCorrelation;
|
import ghidra.program.util.AddressCorrelation;
|
||||||
import ghidra.program.util.DiscoverableAddressCorrelator;
|
import ghidra.program.util.AddressCorrelator;
|
||||||
|
|
||||||
public class CodeCompareAddressCorrelator implements DiscoverableAddressCorrelator {
|
public class CodeCompareAddressCorrelator implements AddressCorrelator {
|
||||||
|
|
||||||
private static final String OPTIONS_NAME = "CodeCompareAddressCorrelator";
|
private static final String OPTIONS_NAME = "CodeCompareAddressCorrelator";
|
||||||
|
|
||||||
|
@ -40,7 +40,9 @@ public class CodeCompareAddressCorrelator implements DiscoverableAddressCorrelat
|
||||||
Language l1 = p1.getLanguage();
|
Language l1 = p1.getLanguage();
|
||||||
Language l2 = p2.getLanguage();
|
Language l2 = p2.getLanguage();
|
||||||
if (l1.getLanguageID().equals(l2.getLanguageID())) {
|
if (l1.getLanguageID().equals(l2.getLanguageID())) {
|
||||||
return null; // this correlator is best used with different architectures
|
// this correlator is best used with different architectures, assuming we have simpler
|
||||||
|
// and faster correlators that should be run with the same language
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new CodeCompareAddressCorrelation(sourceFunction, destinationFunction);
|
return new CodeCompareAddressCorrelation(sourceFunction, destinationFunction);
|
||||||
|
@ -65,4 +67,11 @@ public class CodeCompareAddressCorrelator implements DiscoverableAddressCorrelat
|
||||||
public Options getDefaultOptions() {
|
public Options getDefaultOptions() {
|
||||||
return new ToolOptions(OPTIONS_NAME);
|
return new ToolOptions(OPTIONS_NAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getPriority() {
|
||||||
|
// Run just above the last chance priority, which allows this correlator to be the fallback,
|
||||||
|
// general purpose correlator.
|
||||||
|
return LATE_CHANCE_PRIORITY - PRIORITY_OFFSET;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,8 @@ dependencies {
|
||||||
api project(":Base")
|
api project(":Base")
|
||||||
runtimeOnly project(":CodeCompare")
|
runtimeOnly project(":CodeCompare")
|
||||||
|
|
||||||
|
|
||||||
|
testImplementation project(path: ':CodeCompare', configuration: 'testArtifacts')
|
||||||
testImplementation project(path: ':Project', configuration: 'testArtifacts')
|
testImplementation project(path: ':Project', configuration: 'testArtifacts')
|
||||||
testImplementation project(path: ':SoftwareModeling', configuration: 'testArtifacts')
|
testImplementation project(path: ':SoftwareModeling', configuration: 'testArtifacts')
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,20 +25,13 @@ import ghidra.program.util.*;
|
||||||
* This is the correlator of last resort. It is the last correlator to be checked when trying to
|
* This is the correlator of last resort. It is the last correlator to be checked when trying to
|
||||||
* acquire a correlation.
|
* acquire a correlation.
|
||||||
*/
|
*/
|
||||||
public class LastResortAddressCorrelator implements AddressCorrelator {
|
public class LinearAddressCorrelator implements AddressCorrelator {
|
||||||
|
|
||||||
private static final String CORRELATOR_NAME = "LastResortAddressCorrelator";
|
private static final String CORRELATOR_NAME = "LastResortAddressCorrelator";
|
||||||
private ToolOptions options = new ToolOptions(CORRELATOR_NAME);
|
private ToolOptions options = new ToolOptions(CORRELATOR_NAME);
|
||||||
|
|
||||||
public LastResortAddressCorrelator() {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AddressCorrelation correlate(Function sourceFunction, Function destinationFunction) {
|
public AddressCorrelation correlate(Function sourceFunction, Function destinationFunction) {
|
||||||
if (sourceFunction.getProgram().getLanguage().getLanguageDescription().getProcessor().equals(
|
|
||||||
destinationFunction.getProgram().getLanguage().getLanguageDescription().getProcessor())) {
|
|
||||||
return new VTHashedFunctionAddressCorrelation(sourceFunction, destinationFunction);
|
|
||||||
}
|
|
||||||
return new LinearFunctionAddressCorrelation(sourceFunction, destinationFunction);
|
return new LinearFunctionAddressCorrelation(sourceFunction, destinationFunction);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,4 +54,9 @@ public class LastResortAddressCorrelator implements AddressCorrelator {
|
||||||
public Options getDefaultOptions() {
|
public Options getDefaultOptions() {
|
||||||
return new ToolOptions(CORRELATOR_NAME);
|
return new ToolOptions(CORRELATOR_NAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getPriority() {
|
||||||
|
return LATE_CHANCE_PRIORITY;
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -21,6 +21,7 @@ import java.util.Map;
|
||||||
import ghidra.program.model.address.*;
|
import ghidra.program.model.address.*;
|
||||||
import ghidra.program.model.listing.*;
|
import ghidra.program.model.listing.*;
|
||||||
import ghidra.program.util.AddressCorrelation;
|
import ghidra.program.util.AddressCorrelation;
|
||||||
|
import ghidra.program.util.AddressCorrelationRange;
|
||||||
import ghidra.util.exception.CancelledException;
|
import ghidra.util.exception.CancelledException;
|
||||||
import ghidra.util.task.TaskMonitor;
|
import ghidra.util.task.TaskMonitor;
|
||||||
|
|
||||||
|
@ -52,29 +53,37 @@ public class StraightLineCorrelation implements AddressCorrelation {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AddressRange getCorrelatedDestinationRange(Address sourceAddress, TaskMonitor monitor)
|
public AddressCorrelationRange getCorrelatedDestinationRange(Address sourceAddress,
|
||||||
throws CancelledException {
|
TaskMonitor monitor) throws CancelledException {
|
||||||
initialize(monitor);
|
initialize(monitor);
|
||||||
return cachedForwardAddressMap.get(sourceAddress);
|
AddressRange range = cachedForwardAddressMap.get(sourceAddress);
|
||||||
|
return new AddressCorrelationRange(range, getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initialize(TaskMonitor monitor) throws CancelledException {
|
private void initialize(TaskMonitor monitor) throws CancelledException {
|
||||||
|
|
||||||
if (cachedForwardAddressMap != null) return;
|
if (cachedForwardAddressMap != null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
cachedForwardAddressMap = new HashMap<Address, AddressRange>();
|
cachedForwardAddressMap = new HashMap<Address, AddressRange>();
|
||||||
|
|
||||||
AddressSetView sourceAddressSet = (sourceFunction != null) ? sourceFunction.getBody() : null;
|
AddressSetView sourceAddressSet =
|
||||||
AddressSetView destinationAddressSet = (destinationFunction != null) ? destinationFunction.getBody() : null;
|
(sourceFunction != null) ? sourceFunction.getBody() : null;
|
||||||
|
AddressSetView destinationAddressSet =
|
||||||
|
(destinationFunction != null) ? destinationFunction.getBody() : null;
|
||||||
|
|
||||||
if (sourceAddressSet == null || destinationAddressSet == null)
|
if (sourceAddressSet == null || destinationAddressSet == null) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
CodeUnitIterator srcIter = sourceFunction.getProgram().getListing().getCodeUnits(sourceAddressSet, true);
|
CodeUnitIterator srcIter =
|
||||||
CodeUnitIterator destIter = destinationFunction.getProgram().getListing().getCodeUnits(destinationAddressSet, true);
|
sourceFunction.getProgram().getListing().getCodeUnits(sourceAddressSet, true);
|
||||||
|
CodeUnitIterator destIter =
|
||||||
|
destinationFunction.getProgram().getListing().getCodeUnits(destinationAddressSet, true);
|
||||||
|
|
||||||
monitor.setMessage("Defining address ranges...");
|
monitor.setMessage("Defining address ranges...");
|
||||||
monitor.initialize(sourceAddressSet.getNumAddresses());
|
monitor.initialize(sourceAddressSet.getNumAddresses());
|
||||||
while(srcIter.hasNext() && destIter.hasNext()) {
|
while (srcIter.hasNext() && destIter.hasNext()) {
|
||||||
CodeUnit srcCodeUnit = srcIter.next();
|
CodeUnit srcCodeUnit = srcIter.next();
|
||||||
CodeUnit destCodeUnit = destIter.next();
|
CodeUnit destCodeUnit = destIter.next();
|
||||||
String srcMnemonic = srcCodeUnit.getMnemonicString();
|
String srcMnemonic = srcCodeUnit.getMnemonicString();
|
||||||
|
@ -84,8 +93,9 @@ public class StraightLineCorrelation implements AddressCorrelation {
|
||||||
monitor.incrementProgress(srcCodeUnit.getLength());
|
monitor.incrementProgress(srcCodeUnit.getLength());
|
||||||
defineRange(cachedForwardAddressMap, srcCodeUnit, destCodeUnit);
|
defineRange(cachedForwardAddressMap, srcCodeUnit, destCodeUnit);
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
break; // First mismatch we break out of the loop
|
break; // First mismatch we break out of the loop
|
||||||
|
}
|
||||||
}
|
}
|
||||||
computeParamCorrelation();
|
computeParamCorrelation();
|
||||||
}
|
}
|
||||||
|
@ -124,13 +134,12 @@ public class StraightLineCorrelation implements AddressCorrelation {
|
||||||
* @param sourceCodeUnit is the source code unit
|
* @param sourceCodeUnit is the source code unit
|
||||||
* @param destinationCodeUnit is the matching destination code unit
|
* @param destinationCodeUnit is the matching destination code unit
|
||||||
*/
|
*/
|
||||||
private static void defineRange(Map<Address, AddressRange> map,
|
private static void defineRange(Map<Address, AddressRange> map, CodeUnit sourceCodeUnit,
|
||||||
CodeUnit sourceCodeUnit, CodeUnit destinationCodeUnit) {
|
CodeUnit destinationCodeUnit) {
|
||||||
Address minAddress = sourceCodeUnit.getMinAddress();
|
Address minAddress = sourceCodeUnit.getMinAddress();
|
||||||
Address maxAddress = sourceCodeUnit.getMaxAddress();
|
Address maxAddress = sourceCodeUnit.getMaxAddress();
|
||||||
AddressRangeImpl toRange =
|
AddressRangeImpl toRange = new AddressRangeImpl(destinationCodeUnit.getMinAddress(),
|
||||||
new AddressRangeImpl(destinationCodeUnit.getMinAddress(),
|
destinationCodeUnit.getMaxAddress());
|
||||||
destinationCodeUnit.getMaxAddress());
|
|
||||||
while (!minAddress.equals(maxAddress)) {
|
while (!minAddress.equals(maxAddress)) {
|
||||||
map.put(minAddress, toRange);
|
map.put(minAddress, toRange);
|
||||||
minAddress = minAddress.next();
|
minAddress = minAddress.next();
|
||||||
|
|
|
@ -17,7 +17,8 @@ package ghidra.feature.vt.api.correlator.address;
|
||||||
|
|
||||||
import static ghidra.util.datastruct.Duo.Side.*;
|
import static ghidra.util.datastruct.Duo.Side.*;
|
||||||
|
|
||||||
import ghidra.program.model.address.*;
|
import ghidra.program.model.address.Address;
|
||||||
|
import ghidra.program.model.address.AddressRangeImpl;
|
||||||
import ghidra.program.model.correlate.HashedFunctionAddressCorrelation;
|
import ghidra.program.model.correlate.HashedFunctionAddressCorrelation;
|
||||||
import ghidra.program.model.listing.Function;
|
import ghidra.program.model.listing.Function;
|
||||||
import ghidra.program.model.mem.MemoryAccessException;
|
import ghidra.program.model.mem.MemoryAccessException;
|
||||||
|
@ -57,15 +58,16 @@ public class VTHashedFunctionAddressCorrelation implements AddressCorrelation {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AddressRange getCorrelatedDestinationRange(Address sourceAddress, TaskMonitor monitor)
|
public AddressCorrelationRange getCorrelatedDestinationRange(Address sourceAddress,
|
||||||
throws CancelledException {
|
TaskMonitor monitor) throws CancelledException {
|
||||||
try {
|
try {
|
||||||
initializeCorrelation(monitor);
|
initializeCorrelation(monitor);
|
||||||
Address destinationAddress = addressCorrelation.getAddress(RIGHT, sourceAddress);
|
Address destinationAddress = addressCorrelation.getAddress(RIGHT, sourceAddress);
|
||||||
if (destinationAddress == null) {
|
if (destinationAddress == null) {
|
||||||
return null; // No matching destination.
|
return null; // No matching destination.
|
||||||
}
|
}
|
||||||
return new AddressRangeImpl(destinationAddress, destinationAddress);
|
AddressRangeImpl range = new AddressRangeImpl(destinationAddress, destinationAddress);
|
||||||
|
return new AddressCorrelationRange(range, getName());
|
||||||
}
|
}
|
||||||
catch (MemoryAccessException e) {
|
catch (MemoryAccessException e) {
|
||||||
Msg.error(this, "Could not create HashedFunctionAddressCorrelation", e);
|
Msg.error(this, "Could not create HashedFunctionAddressCorrelation", e);
|
||||||
|
@ -81,15 +83,14 @@ public class VTHashedFunctionAddressCorrelation implements AddressCorrelation {
|
||||||
* @throws CancelledException if the user cancels
|
* @throws CancelledException if the user cancels
|
||||||
* @throws MemoryAccessException if either function's memory can't be accessed.
|
* @throws MemoryAccessException if either function's memory can't be accessed.
|
||||||
*/
|
*/
|
||||||
private void initializeCorrelation(TaskMonitor monitor) throws CancelledException,
|
private void initializeCorrelation(TaskMonitor monitor)
|
||||||
MemoryAccessException {
|
throws CancelledException, MemoryAccessException {
|
||||||
if (addressCorrelation != null) {
|
if (addressCorrelation != null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (sourceFunction != null && destinationFunction != null) {
|
if (sourceFunction != null && destinationFunction != null) {
|
||||||
addressCorrelation =
|
addressCorrelation =
|
||||||
new HashedFunctionAddressCorrelation(sourceFunction, destinationFunction,
|
new HashedFunctionAddressCorrelation(sourceFunction, destinationFunction, monitor);
|
||||||
monitor);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
addressCorrelation = new DummyListingAddressCorrelation();
|
addressCorrelation = new DummyListingAddressCorrelation();
|
||||||
|
|
|
@ -0,0 +1,72 @@
|
||||||
|
/* ###
|
||||||
|
* 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.feature.vt.api.correlator.address;
|
||||||
|
|
||||||
|
import ghidra.framework.options.Options;
|
||||||
|
import ghidra.framework.options.ToolOptions;
|
||||||
|
import ghidra.program.model.lang.Language;
|
||||||
|
import ghidra.program.model.listing.Data;
|
||||||
|
import ghidra.program.model.listing.Function;
|
||||||
|
import ghidra.program.util.AddressCorrelation;
|
||||||
|
import ghidra.program.util.AddressCorrelator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An address correlator that may use the {@link VTHashedFunctionAddressCorrelation}.
|
||||||
|
*/
|
||||||
|
public class VTHashedFunctionAddressCorrelator implements AddressCorrelator {
|
||||||
|
|
||||||
|
public static final String NAME = "VTHashedFunctionAddressCorrelator";
|
||||||
|
|
||||||
|
private ToolOptions options = new ToolOptions(NAME);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AddressCorrelation correlate(Function sourceFunction, Function destinationFunction) {
|
||||||
|
|
||||||
|
Language sourceLanguage = sourceFunction.getProgram().getLanguage();
|
||||||
|
Language destinationLanguage = destinationFunction.getProgram().getLanguage();
|
||||||
|
if (sourceLanguage.getProcessor().equals(destinationLanguage.getProcessor())) {
|
||||||
|
return new VTHashedFunctionAddressCorrelation(sourceFunction, destinationFunction);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AddressCorrelation correlate(Data sourceData, Data destinationData) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ToolOptions getOptions() {
|
||||||
|
return options;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setOptions(ToolOptions options) {
|
||||||
|
this.options = options.copy();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Options getDefaultOptions() {
|
||||||
|
return new ToolOptions(NAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getPriority() {
|
||||||
|
// Run just above default / discovered correlators. Correlator authors can change their
|
||||||
|
// priority to take precedence over this correlator.
|
||||||
|
return DEFAULT_PRIORITY - PRIORITY_OFFSET;
|
||||||
|
}
|
||||||
|
}
|
|
@ -44,6 +44,7 @@ public interface VTMarkupItem {
|
||||||
* address and the address source must be set prior to calling this method.
|
* address and the address source must be set prior to calling this method.
|
||||||
*
|
*
|
||||||
* @param applyAction the type of apply action to take when applying the given markup item
|
* @param applyAction the type of apply action to take when applying the given markup item
|
||||||
|
* @param options the options
|
||||||
* @throws VersionTrackingApplyException if an error occurred while attempting to apply the
|
* @throws VersionTrackingApplyException if an error occurred while attempting to apply the
|
||||||
* markup item.
|
* markup item.
|
||||||
*/
|
*/
|
||||||
|
@ -94,7 +95,7 @@ public interface VTMarkupItem {
|
||||||
* Returns the editable status of this markup item's destination address.
|
* Returns the editable status of this markup item's destination address.
|
||||||
*
|
*
|
||||||
* @return the editable status of this markup item's destination address.
|
* @return the editable status of this markup item's destination address.
|
||||||
* @see #setDestinationAddress(Address, String)
|
* @see #setDestinationAddress(Address)
|
||||||
*/
|
*/
|
||||||
public VTMarkupItemDestinationAddressEditStatus getDestinationAddressEditStatus();
|
public VTMarkupItemDestinationAddressEditStatus getDestinationAddressEditStatus();
|
||||||
|
|
||||||
|
@ -110,7 +111,6 @@ public interface VTMarkupItem {
|
||||||
*
|
*
|
||||||
* @param status The <b>considered</b> status to set
|
* @param status The <b>considered</b> status to set
|
||||||
* @throws IllegalStateException if you call this method on an applied item
|
* @throws IllegalStateException if you call this method on an applied item
|
||||||
* @see #setUnconsidered()
|
|
||||||
*/
|
*/
|
||||||
public void setConsidered(VTMarkupItemConsideredStatus status);
|
public void setConsidered(VTMarkupItemConsideredStatus status);
|
||||||
|
|
||||||
|
@ -124,6 +124,7 @@ public interface VTMarkupItem {
|
||||||
* Returns an optional description of the current markup item status. For example, if there
|
* Returns an optional description of the current markup item status. For example, if there
|
||||||
* status is {@link VTMarkupItemStatus#FAILED_APPLY}, then this method should return a
|
* status is {@link VTMarkupItemStatus#FAILED_APPLY}, then this method should return a
|
||||||
* description of the failure.
|
* description of the failure.
|
||||||
|
* @return the description.
|
||||||
*/
|
*/
|
||||||
public String getStatusDescription();
|
public String getStatusDescription();
|
||||||
|
|
||||||
|
|
|
@ -15,9 +15,12 @@
|
||||||
*/
|
*/
|
||||||
package ghidra.feature.vt.api.markuptype;
|
package ghidra.feature.vt.api.markuptype;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import ghidra.feature.vt.api.main.*;
|
import ghidra.feature.vt.api.main.*;
|
||||||
import ghidra.feature.vt.gui.util.*;
|
import ghidra.feature.vt.gui.util.VTMatchApplyChoices;
|
||||||
import ghidra.feature.vt.gui.util.VTMatchApplyChoices.CommentChoices;
|
import ghidra.feature.vt.gui.util.VTMatchApplyChoices.CommentChoices;
|
||||||
|
import ghidra.feature.vt.gui.util.VTOptionDefines;
|
||||||
import ghidra.framework.options.Options;
|
import ghidra.framework.options.Options;
|
||||||
import ghidra.framework.options.ToolOptions;
|
import ghidra.framework.options.ToolOptions;
|
||||||
import ghidra.program.model.address.Address;
|
import ghidra.program.model.address.Address;
|
||||||
|
@ -26,8 +29,6 @@ import ghidra.program.model.listing.Program;
|
||||||
import ghidra.program.util.PlateFieldLocation;
|
import ghidra.program.util.PlateFieldLocation;
|
||||||
import ghidra.program.util.ProgramLocation;
|
import ghidra.program.util.ProgramLocation;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class PlateCommentMarkupType extends CommentMarkupType {
|
public class PlateCommentMarkupType extends CommentMarkupType {
|
||||||
|
|
||||||
//==================================================================================================
|
//==================================================================================================
|
||||||
|
@ -102,14 +103,16 @@ public class PlateCommentMarkupType extends CommentMarkupType {
|
||||||
options.setEnum(VTOptionDefines.PLATE_COMMENT, CommentChoices.APPEND_TO_EXISTING);
|
options.setEnum(VTOptionDefines.PLATE_COMMENT, CommentChoices.APPEND_TO_EXISTING);
|
||||||
break;
|
break;
|
||||||
case ADD_AS_PRIMARY:
|
case ADD_AS_PRIMARY:
|
||||||
throw new IllegalArgumentException(getDisplayName() +
|
throw new IllegalArgumentException(
|
||||||
" markup items cannot perform an Add As Primary action.");
|
getDisplayName() + " markup items cannot perform an Add As Primary action.");
|
||||||
case REPLACE_DEFAULT_ONLY:
|
case REPLACE_DEFAULT_ONLY:
|
||||||
throw new IllegalArgumentException(getDisplayName() +
|
throw new IllegalArgumentException(getDisplayName() +
|
||||||
" markup items cannot perform a Replace Default Only action.");
|
" markup items cannot perform a Replace Default Only action.");
|
||||||
case REPLACE:
|
case REPLACE:
|
||||||
options.setEnum(VTOptionDefines.PLATE_COMMENT, CommentChoices.OVERWRITE_EXISTING);
|
options.setEnum(VTOptionDefines.PLATE_COMMENT, CommentChoices.OVERWRITE_EXISTING);
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return options;
|
return options;
|
||||||
}
|
}
|
||||||
|
@ -124,7 +127,7 @@ public class PlateCommentMarkupType extends CommentMarkupType {
|
||||||
if (vtMarkupItem.getSourceAddress().equals(association.getSourceAddress())) {
|
if (vtMarkupItem.getSourceAddress().equals(association.getSourceAddress())) {
|
||||||
// Set Plate destination to destination function's entry point.
|
// Set Plate destination to destination function's entry point.
|
||||||
vtMarkupItem.setDefaultDestinationAddress(association.getDestinationAddress(),
|
vtMarkupItem.setDefaultDestinationAddress(association.getDestinationAddress(),
|
||||||
VTMarkupItem.FUNCTION_ADDRESS_SOURCE);
|
VTMarkupItem.FUNCTION_ADDRESS_SOURCE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return markupItems;
|
return markupItems;
|
||||||
|
|
|
@ -22,7 +22,8 @@ import org.jdom.Element;
|
||||||
import generic.cache.FixedSizeMRUCachingFactory;
|
import generic.cache.FixedSizeMRUCachingFactory;
|
||||||
import generic.stl.Pair;
|
import generic.stl.Pair;
|
||||||
import ghidra.feature.vt.api.correlator.address.ExactMatchAddressCorrelator;
|
import ghidra.feature.vt.api.correlator.address.ExactMatchAddressCorrelator;
|
||||||
import ghidra.feature.vt.api.correlator.address.LastResortAddressCorrelator;
|
import ghidra.feature.vt.api.correlator.address.VTHashedFunctionAddressCorrelator;
|
||||||
|
import ghidra.features.codecompare.correlator.CodeCompareAddressCorrelator;
|
||||||
import ghidra.framework.options.*;
|
import ghidra.framework.options.*;
|
||||||
import ghidra.program.model.listing.Data;
|
import ghidra.program.model.listing.Data;
|
||||||
import ghidra.program.model.listing.Function;
|
import ghidra.program.model.listing.Function;
|
||||||
|
@ -37,6 +38,20 @@ public class AddressCorrelatorManager {
|
||||||
|
|
||||||
private static final int DATA_CORRELATION_CACHE_SIZE = 5;
|
private static final int DATA_CORRELATION_CACHE_SIZE = 5;
|
||||||
private static final int FUNCTION_CORRELATION_CACHE_SIZE = 5;
|
private static final int FUNCTION_CORRELATION_CACHE_SIZE = 5;
|
||||||
|
private static final Comparator<? super AddressCorrelator> CORRELATOR_COMPARATOR = (c1, c2) -> {
|
||||||
|
|
||||||
|
int p1 = c1.getPriority();
|
||||||
|
int p2 = c2.getPriority();
|
||||||
|
int d = p1 - p2;
|
||||||
|
if (d != 0) {
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
|
||||||
|
// pick something as a tie-breaker
|
||||||
|
String n1 = c1.getClass().getSimpleName();
|
||||||
|
String n2 = c2.getClass().getSimpleName();
|
||||||
|
return n1.compareTo(n2);
|
||||||
|
};
|
||||||
|
|
||||||
private List<AddressCorrelator> correlatorList;
|
private List<AddressCorrelator> correlatorList;
|
||||||
|
|
||||||
|
@ -55,22 +70,25 @@ public class AddressCorrelatorManager {
|
||||||
|
|
||||||
private void initializeAddressCorrelators(VTSessionSupplier sessionSupplier) {
|
private void initializeAddressCorrelators(VTSessionSupplier sessionSupplier) {
|
||||||
correlatorList.add(new ExactMatchAddressCorrelator(sessionSupplier));
|
correlatorList.add(new ExactMatchAddressCorrelator(sessionSupplier));
|
||||||
|
correlatorList.add(new VTHashedFunctionAddressCorrelator());
|
||||||
|
correlatorList.add(new CodeCompareAddressCorrelator());
|
||||||
|
|
||||||
|
// Note: at the time of writing this comment, the linear address correlator will not be
|
||||||
|
// executed. The VTHashedFunctionAddressCorrelator handles correlation between programs
|
||||||
|
// with the same architecture and the CodeCompareAddressCorrelator handles correlation
|
||||||
|
// between programs with different architectures.
|
||||||
|
// correlatorList.add(new LinearAddressCorrelator());
|
||||||
|
|
||||||
correlatorList.addAll(initializeAddressCorrelators());
|
correlatorList.addAll(initializeAddressCorrelators());
|
||||||
|
|
||||||
|
correlatorList.sort(CORRELATOR_COMPARATOR);
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<AddressCorrelator> initializeAddressCorrelators() {
|
private List<AddressCorrelator> initializeAddressCorrelators() {
|
||||||
|
|
||||||
List<DiscoverableAddressCorrelator> instances =
|
List<DiscoverableAddressCorrelator> instances =
|
||||||
ClassSearcher.getInstances(DiscoverableAddressCorrelator.class);
|
ClassSearcher.getInstances(DiscoverableAddressCorrelator.class);
|
||||||
List<AddressCorrelator> addressCorrelatorList = new ArrayList<AddressCorrelator>(instances);
|
return new ArrayList<AddressCorrelator>(instances);
|
||||||
|
|
||||||
Collections.sort(addressCorrelatorList,
|
|
||||||
(o1, o2) -> o1.getClass().getSimpleName().compareTo(o2.getClass().getSimpleName()));
|
|
||||||
|
|
||||||
// Put the LastResortCorrelator in case a better address correlation isn't found.
|
|
||||||
addressCorrelatorList.add(new LastResortAddressCorrelator());
|
|
||||||
|
|
||||||
return addressCorrelatorList;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public AddressCorrelation getCorrelator(Function source, Function destination) {
|
public AddressCorrelation getCorrelator(Function source, Function destination) {
|
||||||
|
@ -82,6 +100,7 @@ public class AddressCorrelatorManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
private AddressCorrelation getFunctionCorrelator(Function source, Function destination) {
|
private AddressCorrelation getFunctionCorrelator(Function source, Function destination) {
|
||||||
|
|
||||||
for (AddressCorrelator correlator : correlatorList) {
|
for (AddressCorrelator correlator : correlatorList) {
|
||||||
AddressCorrelation correlation = correlator.correlate(source, destination);
|
AddressCorrelation correlation = correlator.correlate(source, destination);
|
||||||
if (correlation != null) {
|
if (correlation != null) {
|
||||||
|
@ -92,12 +111,14 @@ public class AddressCorrelatorManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
private AddressCorrelation getDataCorrelator(Data source, Data destination) {
|
private AddressCorrelation getDataCorrelator(Data source, Data destination) {
|
||||||
|
|
||||||
for (AddressCorrelator correlator : correlatorList) {
|
for (AddressCorrelator correlator : correlatorList) {
|
||||||
AddressCorrelation correlation = correlator.correlate(source, destination);
|
AddressCorrelation correlation = correlator.correlate(source, destination);
|
||||||
if (correlation != null) {
|
if (correlation != null) {
|
||||||
return correlation;
|
return correlation;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1153,13 +1153,18 @@ public class VTMatchTableProvider extends ComponentProviderAdapter
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isSubFilterOf(Filter<VTMatch> otherFilter) {
|
public boolean isSubFilterOf(Filter<VTMatch> otherFilter) {
|
||||||
if (columnFilter == null) {
|
|
||||||
return false;
|
Class<?> clazz = getClass();
|
||||||
|
Class<?> otherClazz = otherFilter.getClass();
|
||||||
|
if (!clazz.equals(otherClazz)) {
|
||||||
|
return false; // must be the same class
|
||||||
}
|
}
|
||||||
if (otherFilter instanceof VTColumnFilter otherColumnFilter) {
|
|
||||||
return columnFilter.isSubFilterOf(otherColumnFilter.columnFilter);
|
VTColumnFilter otherColumnFilter = (VTColumnFilter) otherFilter;
|
||||||
|
if (columnFilter == null && otherColumnFilter.columnFilter == null) {
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return columnFilter.isSubFilterOf(otherColumnFilter.columnFilter);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,10 +25,10 @@ import ghidra.feature.vt.api.util.VersionTrackingApplyException;
|
||||||
import ghidra.feature.vt.gui.plugin.VTController;
|
import ghidra.feature.vt.gui.plugin.VTController;
|
||||||
import ghidra.feature.vt.gui.util.MatchInfo;
|
import ghidra.feature.vt.gui.util.MatchInfo;
|
||||||
import ghidra.program.model.address.Address;
|
import ghidra.program.model.address.Address;
|
||||||
import ghidra.program.model.address.AddressRange;
|
|
||||||
import ghidra.program.model.listing.Data;
|
import ghidra.program.model.listing.Data;
|
||||||
import ghidra.program.model.listing.Function;
|
import ghidra.program.model.listing.Function;
|
||||||
import ghidra.program.util.AddressCorrelation;
|
import ghidra.program.util.AddressCorrelation;
|
||||||
|
import ghidra.program.util.AddressCorrelationRange;
|
||||||
import ghidra.util.exception.AssertException;
|
import ghidra.util.exception.AssertException;
|
||||||
import ghidra.util.exception.CancelledException;
|
import ghidra.util.exception.CancelledException;
|
||||||
import ghidra.util.task.TaskMonitor;
|
import ghidra.util.task.TaskMonitor;
|
||||||
|
@ -133,13 +133,16 @@ public class ClearMatchTask extends VtTask {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Address destinationAddress = null;
|
AddressCorrelationRange range =
|
||||||
AddressRange range =
|
|
||||||
correlation.getCorrelatedDestinationRange(markupItem.getSourceAddress(), monitor);
|
correlation.getCorrelatedDestinationRange(markupItem.getSourceAddress(), monitor);
|
||||||
|
Address destinationAddress = null;
|
||||||
|
String source = null;
|
||||||
if (range != null) {
|
if (range != null) {
|
||||||
destinationAddress = range.getMinAddress();
|
destinationAddress = range.getMinAddress();
|
||||||
|
source = range.getCorrelatorName();
|
||||||
}
|
}
|
||||||
markupItem.setDefaultDestinationAddress(destinationAddress, correlation.getName());
|
markupItem.setDefaultDestinationAddress(destinationAddress, source);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void clearMatch(VTMatch match) {
|
private void clearMatch(VTMatch match) {
|
||||||
|
|
|
@ -21,8 +21,8 @@ import ghidra.feature.vt.api.db.VTSessionDB;
|
||||||
import ghidra.feature.vt.api.main.*;
|
import ghidra.feature.vt.api.main.*;
|
||||||
import ghidra.feature.vt.api.util.VersionTrackingApplyException;
|
import ghidra.feature.vt.api.util.VersionTrackingApplyException;
|
||||||
import ghidra.program.model.address.Address;
|
import ghidra.program.model.address.Address;
|
||||||
import ghidra.program.model.address.AddressRange;
|
|
||||||
import ghidra.program.util.AddressCorrelation;
|
import ghidra.program.util.AddressCorrelation;
|
||||||
|
import ghidra.program.util.AddressCorrelationRange;
|
||||||
import ghidra.util.exception.CancelledException;
|
import ghidra.util.exception.CancelledException;
|
||||||
import ghidra.util.task.TaskMonitor;
|
import ghidra.util.task.TaskMonitor;
|
||||||
|
|
||||||
|
@ -90,11 +90,11 @@ public class UnapplyMarkupItemTask extends VtTask {
|
||||||
Address destinationAddress = null;
|
Address destinationAddress = null;
|
||||||
String source = null;
|
String source = null;
|
||||||
if (correlation != null) {
|
if (correlation != null) {
|
||||||
AddressRange range =
|
AddressCorrelationRange range =
|
||||||
correlation.getCorrelatedDestinationRange(markupItem.getSourceAddress(), monitor);
|
correlation.getCorrelatedDestinationRange(markupItem.getSourceAddress(), monitor);
|
||||||
if (range != null) {
|
if (range != null) {
|
||||||
destinationAddress = range.getMinAddress();
|
destinationAddress = range.getMinAddress();
|
||||||
source = correlation.getName();
|
source = range.getCorrelatorName();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,7 @@ import ghidra.program.model.address.*;
|
||||||
import ghidra.program.model.listing.*;
|
import ghidra.program.model.listing.*;
|
||||||
import ghidra.program.model.symbol.*;
|
import ghidra.program.model.symbol.*;
|
||||||
import ghidra.program.util.AddressCorrelation;
|
import ghidra.program.util.AddressCorrelation;
|
||||||
|
import ghidra.program.util.AddressCorrelationRange;
|
||||||
import ghidra.util.exception.CancelledException;
|
import ghidra.util.exception.CancelledException;
|
||||||
import ghidra.util.task.TaskMonitor;
|
import ghidra.util.task.TaskMonitor;
|
||||||
|
|
||||||
|
@ -191,7 +192,8 @@ public class ImpliedMatchUtils {
|
||||||
Address srcRefFromAddress = sourceRef.getFromAddress();
|
Address srcRefFromAddress = sourceRef.getFromAddress();
|
||||||
|
|
||||||
// Get the destination reference address corresponding to the given source reference address
|
// Get the destination reference address corresponding to the given source reference address
|
||||||
AddressRange range = correlator.getCorrelatedDestinationRange(srcRefFromAddress, monitor);
|
AddressCorrelationRange range =
|
||||||
|
correlator.getCorrelatedDestinationRange(srcRefFromAddress, monitor);
|
||||||
if (range == null) {
|
if (range == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -147,8 +147,8 @@ public class MatchInfo {
|
||||||
return markupItemsCache.get(monitor);
|
return markupItemsCache.get(monitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setDefaultDestination(VTMarkupItem markupItem,
|
private void setDefaultDestination(VTMarkupItem markupItem, AddressCorrelation correlation,
|
||||||
AddressCorrelation addressTranslator, TaskMonitor monitor) throws CancelledException {
|
TaskMonitor monitor) throws CancelledException {
|
||||||
|
|
||||||
Address destinationAddress = getDestinationAddress(markupItem);
|
Address destinationAddress = getDestinationAddress(markupItem);
|
||||||
Address sourceAddress = markupItem.getSourceAddress();
|
Address sourceAddress = markupItem.getSourceAddress();
|
||||||
|
@ -158,12 +158,12 @@ public class MatchInfo {
|
||||||
}
|
}
|
||||||
|
|
||||||
String destinationAddressSource = null;
|
String destinationAddressSource = null;
|
||||||
if (addressTranslator != null) {
|
if (correlation != null) {
|
||||||
AddressRange correlatedDestinationRange =
|
AddressCorrelationRange range =
|
||||||
addressTranslator.getCorrelatedDestinationRange(sourceAddress, monitor);
|
correlation.getCorrelatedDestinationRange(sourceAddress, monitor);
|
||||||
if (correlatedDestinationRange != null) {
|
if (range != null) {
|
||||||
destinationAddress = correlatedDestinationRange.getMinAddress();
|
destinationAddress = range.getMinAddress();
|
||||||
destinationAddressSource = addressTranslator.getName();
|
destinationAddressSource = range.getCorrelatorName();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -204,22 +204,23 @@ public class MatchInfo {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
AddressCorrelation addressTranslator = getAddressTranslator(correlatorMgr);
|
AddressCorrelation correlation = getAddressTranslator(correlatorMgr);
|
||||||
if (addressTranslator == null) {
|
if (correlation == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
AddressRange correlatedDestinationRange = null;
|
|
||||||
|
AddressCorrelationRange range = null;
|
||||||
try {
|
try {
|
||||||
correlatedDestinationRange =
|
range = correlation.getCorrelatedDestinationRange(sourceAddress, TaskMonitor.DUMMY);
|
||||||
addressTranslator.getCorrelatedDestinationRange(sourceAddress, TaskMonitor.DUMMY);
|
|
||||||
}
|
}
|
||||||
catch (CancelledException e) {
|
catch (CancelledException e) {
|
||||||
// check for null below
|
// check for null below
|
||||||
}
|
}
|
||||||
if (correlatedDestinationRange == null) {
|
|
||||||
|
if (range == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return correlatedDestinationRange.getMinAddress();
|
return range.getMinAddress();
|
||||||
}
|
}
|
||||||
|
|
||||||
public VTMarkupItem getCurrentMarkupForLocation(ProgramLocation programLocation,
|
public VTMarkupItem getCurrentMarkupForLocation(ProgramLocation programLocation,
|
||||||
|
|
|
@ -17,7 +17,7 @@ package ghidra.feature.vt.api;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertNotNull;
|
import static org.junit.Assert.assertNotNull;
|
||||||
import ghidra.feature.vt.api.correlator.address.LastResortAddressCorrelator;
|
import ghidra.feature.vt.api.correlator.address.LinearAddressCorrelator;
|
||||||
import ghidra.feature.vt.gui.plugin.*;
|
import ghidra.feature.vt.gui.plugin.*;
|
||||||
import ghidra.framework.options.Options;
|
import ghidra.framework.options.Options;
|
||||||
import ghidra.framework.options.SaveState;
|
import ghidra.framework.options.SaveState;
|
||||||
|
@ -61,7 +61,7 @@ public class VTControllerTest extends AbstractGhidraHeadedIntegrationTest {
|
||||||
assertNotNull("The controller did not find any correlators", correlator);
|
assertNotNull("The controller did not find any correlators", correlator);
|
||||||
|
|
||||||
// set some options settings
|
// set some options settings
|
||||||
Options options = correlator.getOptions(LastResortAddressCorrelator.class);
|
Options options = correlator.getOptions(LinearAddressCorrelator.class);
|
||||||
String testDefaultValue = "Test Default Value";
|
String testDefaultValue = "Test Default Value";
|
||||||
String testOptionKey = "Test Option Name";
|
String testOptionKey = "Test Option Name";
|
||||||
String value = options.getString(testOptionKey, testDefaultValue);
|
String value = options.getString(testOptionKey, testDefaultValue);
|
||||||
|
@ -70,7 +70,7 @@ public class VTControllerTest extends AbstractGhidraHeadedIntegrationTest {
|
||||||
String firstNewOptionValue = "New Option Value";
|
String firstNewOptionValue = "New Option Value";
|
||||||
options.setString(testOptionKey, firstNewOptionValue);
|
options.setString(testOptionKey, firstNewOptionValue);
|
||||||
assertEquals(firstNewOptionValue, options.getString(testOptionKey, null));
|
assertEquals(firstNewOptionValue, options.getString(testOptionKey, null));
|
||||||
correlator.setOptions(LastResortAddressCorrelator.class, options);
|
correlator.setOptions(LinearAddressCorrelator.class, options);
|
||||||
// save the options
|
// save the options
|
||||||
SaveState saveState = new SaveState();
|
SaveState saveState = new SaveState();
|
||||||
controller.writeConfigState(saveState);
|
controller.writeConfigState(saveState);
|
||||||
|
@ -78,12 +78,12 @@ public class VTControllerTest extends AbstractGhidraHeadedIntegrationTest {
|
||||||
// change the options
|
// change the options
|
||||||
String secondNewValue = "Second New Value";
|
String secondNewValue = "Second New Value";
|
||||||
options.setString(testOptionKey, secondNewValue);
|
options.setString(testOptionKey, secondNewValue);
|
||||||
correlator.setOptions(LastResortAddressCorrelator.class, options);
|
correlator.setOptions(LinearAddressCorrelator.class, options);
|
||||||
|
|
||||||
// pull the values again and make sure they are still correct (that writing the config
|
// pull the values again and make sure they are still correct (that writing the config
|
||||||
// state did not change the cached controller and options)
|
// state did not change the cached controller and options)
|
||||||
correlator = controller.getCorrelator();
|
correlator = controller.getCorrelator();
|
||||||
options = correlator.getOptions(LastResortAddressCorrelator.class);
|
options = correlator.getOptions(LinearAddressCorrelator.class);
|
||||||
assertEquals(secondNewValue, options.getString(testOptionKey, null));
|
assertEquals(secondNewValue, options.getString(testOptionKey, null));
|
||||||
|
|
||||||
// restore the options
|
// restore the options
|
||||||
|
@ -93,7 +93,7 @@ public class VTControllerTest extends AbstractGhidraHeadedIntegrationTest {
|
||||||
// (we have to pull the correlator and options again, as changing the config state may
|
// (we have to pull the correlator and options again, as changing the config state may
|
||||||
// change the cached values in the controller)
|
// change the cached values in the controller)
|
||||||
correlator = controller.getCorrelator();
|
correlator = controller.getCorrelator();
|
||||||
options = correlator.getOptions(LastResortAddressCorrelator.class);
|
options = correlator.getOptions(LinearAddressCorrelator.class);
|
||||||
assertEquals(firstNewOptionValue, options.getString(testOptionKey, null));
|
assertEquals(firstNewOptionValue, options.getString(testOptionKey, null));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,14 +30,12 @@ import ghidra.feature.vt.api.markuptype.*;
|
||||||
import ghidra.feature.vt.api.util.Stringable;
|
import ghidra.feature.vt.api.util.Stringable;
|
||||||
import ghidra.feature.vt.gui.VTTestEnv;
|
import ghidra.feature.vt.gui.VTTestEnv;
|
||||||
import ghidra.feature.vt.gui.plugin.VTController;
|
import ghidra.feature.vt.gui.plugin.VTController;
|
||||||
|
import ghidra.features.codecompare.correlator.CodeCompareAddressCorrelation;
|
||||||
import ghidra.program.database.ProgramBuilder;
|
import ghidra.program.database.ProgramBuilder;
|
||||||
import ghidra.program.model.address.Address;
|
import ghidra.program.model.address.Address;
|
||||||
import ghidra.program.model.address.AddressRange;
|
|
||||||
import ghidra.program.model.listing.*;
|
import ghidra.program.model.listing.*;
|
||||||
import ghidra.program.model.symbol.SourceType;
|
import ghidra.program.model.symbol.SourceType;
|
||||||
import ghidra.program.util.AddressCorrelation;
|
|
||||||
import ghidra.test.AbstractGhidraHeadedIntegrationTest;
|
import ghidra.test.AbstractGhidraHeadedIntegrationTest;
|
||||||
import ghidra.util.exception.CancelledException;
|
|
||||||
import ghidra.util.task.TaskMonitor;
|
import ghidra.util.task.TaskMonitor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -91,12 +89,13 @@ public class AddressCorrelationTest extends AbstractGhidraHeadedIntegrationTest
|
||||||
createSession(TEST_SOURCE_PROGRAM_NAME, TEST_DESTINATION_PROGRAM_NAME);
|
createSession(TEST_SOURCE_PROGRAM_NAME, TEST_DESTINATION_PROGRAM_NAME);
|
||||||
vtTestEnv.showTool();
|
vtTestEnv.showTool();
|
||||||
addComment(CodeUnit.EOL_COMMENT, "0x0041222b", "Exact bytes comment.");
|
addComment(CodeUnit.EOL_COMMENT, "0x0041222b", "Exact bytes comment.");
|
||||||
addProgramCorrelation(new ExactMatchBytesProgramCorrelatorFactory());
|
|
||||||
useMatch("0x00412210", "0x004121f0");
|
runCorrelator(new ExactMatchBytesProgramCorrelatorFactory());
|
||||||
checkAddressCorrelation(StraightLineCorrelation.NAME);
|
selectMatch("0x00412210", "0x004121f0");
|
||||||
checkCommentMarkup(EolCommentMarkupType.INSTANCE, "0x0041222b", "Exact bytes comment.",
|
|
||||||
"0x0041220b");
|
validateCommentMarkupItems(EolCommentMarkupType.INSTANCE, "0x0041222b",
|
||||||
checkMarkupDestinationSource(StraightLineCorrelation.NAME, false);
|
"Exact bytes comment.", "0x0041220b");
|
||||||
|
validateMarkupDestinationAddress(StraightLineCorrelation.NAME, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -105,12 +104,13 @@ public class AddressCorrelationTest extends AbstractGhidraHeadedIntegrationTest
|
||||||
createSession(TEST_SOURCE_PROGRAM_NAME, TEST_DESTINATION_PROGRAM_NAME);
|
createSession(TEST_SOURCE_PROGRAM_NAME, TEST_DESTINATION_PROGRAM_NAME);
|
||||||
vtTestEnv.showTool();
|
vtTestEnv.showTool();
|
||||||
addComment(CodeUnit.PRE_COMMENT, "0x00412988", "Exact mnemonics comment.");
|
addComment(CodeUnit.PRE_COMMENT, "0x00412988", "Exact mnemonics comment.");
|
||||||
addProgramCorrelation(new ExactMatchMnemonicsProgramCorrelatorFactory());
|
|
||||||
useMatch("0x00412950", "0x00412930");
|
runCorrelator(new ExactMatchMnemonicsProgramCorrelatorFactory());
|
||||||
checkAddressCorrelation(StraightLineCorrelation.NAME);
|
selectMatch("0x00412950", "0x00412930");
|
||||||
checkCommentMarkup(PreCommentMarkupType.INSTANCE, "0x00412988", "Exact mnemonics comment.",
|
|
||||||
"0x00412968");
|
validateCommentMarkupItems(PreCommentMarkupType.INSTANCE, "0x00412988",
|
||||||
checkMarkupDestinationSource(StraightLineCorrelation.NAME, false);
|
"Exact mnemonics comment.", "0x00412968");
|
||||||
|
validateMarkupDestinationAddress(StraightLineCorrelation.NAME, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -119,12 +119,13 @@ public class AddressCorrelationTest extends AbstractGhidraHeadedIntegrationTest
|
||||||
createSession(TEST_SOURCE_PROGRAM_NAME, TEST_DESTINATION_PROGRAM_NAME);
|
createSession(TEST_SOURCE_PROGRAM_NAME, TEST_DESTINATION_PROGRAM_NAME);
|
||||||
vtTestEnv.showTool();
|
vtTestEnv.showTool();
|
||||||
addComment(CodeUnit.POST_COMMENT, "0x004129a2", "Exact instructions comment.");
|
addComment(CodeUnit.POST_COMMENT, "0x004129a2", "Exact instructions comment.");
|
||||||
addProgramCorrelation(new ExactMatchInstructionsProgramCorrelatorFactory());
|
|
||||||
useMatch("0x00412950", "0x00412930");
|
runCorrelator(new ExactMatchInstructionsProgramCorrelatorFactory());
|
||||||
checkAddressCorrelation(StraightLineCorrelation.NAME);
|
selectMatch("0x00412950", "0x00412930");
|
||||||
checkCommentMarkup(PostCommentMarkupType.INSTANCE, "0x004129a2",
|
|
||||||
|
validateCommentMarkupItems(PostCommentMarkupType.INSTANCE, "0x004129a2",
|
||||||
"Exact instructions comment.", "0x00412982");
|
"Exact instructions comment.", "0x00412982");
|
||||||
checkMarkupDestinationSource(StraightLineCorrelation.NAME, false);
|
validateMarkupDestinationAddress(StraightLineCorrelation.NAME, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -135,14 +136,15 @@ public class AddressCorrelationTest extends AbstractGhidraHeadedIntegrationTest
|
||||||
vtTestEnv.showTool();
|
vtTestEnv.showTool();
|
||||||
addComment(CodeUnit.EOL_COMMENT, "0x004126dd", "Similar name eol comment.");
|
addComment(CodeUnit.EOL_COMMENT, "0x004126dd", "Similar name eol comment.");
|
||||||
addComment(CodeUnit.PRE_COMMENT, "0x004126d7", "Similar name pre comment.");
|
addComment(CodeUnit.PRE_COMMENT, "0x004126d7", "Similar name pre comment.");
|
||||||
addProgramCorrelation(new SimilarSymbolNameProgramCorrelatorFactory());
|
|
||||||
useMatch("0x00412690", "0x00412720");
|
runCorrelator(new SimilarSymbolNameProgramCorrelatorFactory());
|
||||||
checkAddressCorrelation(VTHashedFunctionAddressCorrelation.NAME);
|
selectMatch("0x00412690", "0x00412720");
|
||||||
checkCommentMarkup(EolCommentMarkupType.INSTANCE, "0x004126dd", "Similar name eol comment.",
|
|
||||||
"0x0041277f");
|
validateCommentMarkupItems(EolCommentMarkupType.INSTANCE, "0x004126dd",
|
||||||
checkCommentMarkup(PreCommentMarkupType.INSTANCE, "0x004126d7", "Similar name pre comment.",
|
"Similar name eol comment.", "0x0041277f");
|
||||||
"NO_ADDRESS");
|
validateCommentMarkupItems(PreCommentMarkupType.INSTANCE, "0x004126d7",
|
||||||
checkMarkupDestinationSource(VTHashedFunctionAddressCorrelation.NAME, true);
|
"Similar name pre comment.", "NO_ADDRESS");
|
||||||
|
validateMarkupDestinationAddress(VTHashedFunctionAddressCorrelation.NAME, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -154,15 +156,26 @@ public class AddressCorrelationTest extends AbstractGhidraHeadedIntegrationTest
|
||||||
|
|
||||||
createSession(languageProgram1, languageProgram2);
|
createSession(languageProgram1, languageProgram2);
|
||||||
vtTestEnv.showTool();
|
vtTestEnv.showTool();
|
||||||
|
|
||||||
|
// add source comment
|
||||||
addComment(CodeUnit.PLATE_COMMENT, "0x00401003",
|
addComment(CodeUnit.PLATE_COMMENT, "0x00401003",
|
||||||
"Similar name plate comment not at entry.");
|
"Similar name plate comment not at entry.");
|
||||||
addProgramCorrelation(new SimilarSymbolNameProgramCorrelatorFactory());
|
|
||||||
useMatch("0x00401000", "0x00402000");
|
// create correlation run
|
||||||
checkAddressCorrelation(LinearFunctionAddressCorrelation.NAME);
|
runCorrelator(new SimilarSymbolNameProgramCorrelatorFactory());
|
||||||
// Check for our linear function correlation even though destination will be offcut.
|
|
||||||
checkCommentMarkup(PlateCommentMarkupType.INSTANCE, "0x00401003",
|
// accept a match
|
||||||
"Similar name plate comment not at entry.", "0x00402003");
|
selectMatch("0x00401000", "0x00402000");
|
||||||
checkMarkupDestinationSource(LinearFunctionAddressCorrelation.NAME, false);
|
|
||||||
|
// Verify the entry point plate comment markup has a destination address.
|
||||||
|
validateCommentMarkupItems(PlateCommentMarkupType.INSTANCE, "0x00401000",
|
||||||
|
"First plate comment.", "0x00402000");
|
||||||
|
|
||||||
|
// The non-entry point plate comment markup has no address found when using the
|
||||||
|
// Code Compare correlators
|
||||||
|
validateCommentMarkupItems(PlateCommentMarkupType.INSTANCE, "0x00401003",
|
||||||
|
"Similar name plate comment not at entry.", "NO_ADDRESS");
|
||||||
|
validateMarkupDestinationAddress(CodeCompareAddressCorrelation.NAME, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -170,18 +183,18 @@ public class AddressCorrelationTest extends AbstractGhidraHeadedIntegrationTest
|
||||||
// Test a function match created by the Similar Symbol Name correlator where the
|
// Test a function match created by the Similar Symbol Name correlator where the
|
||||||
// two programs are for different languages but the same processor with different
|
// two programs are for different languages but the same processor with different
|
||||||
// instructions.
|
// instructions.
|
||||||
Program languageProgram1 = buildProgram1("language1");
|
Program p1 = buildProgram1("language1");
|
||||||
Program languageProgram2 = buildProgram3("language3");
|
Program p2 = buildProgram3("language3");
|
||||||
|
createSession(p1, p2);
|
||||||
createSession(languageProgram1, languageProgram2);
|
|
||||||
vtTestEnv.showTool();
|
vtTestEnv.showTool();
|
||||||
addComment(CodeUnit.EOL_COMMENT, "0x00401003", "Similar name eol comment.");
|
addComment(CodeUnit.EOL_COMMENT, "0x00401003", "Similar name eol comment.");
|
||||||
addProgramCorrelation(new SimilarSymbolNameProgramCorrelatorFactory());
|
|
||||||
useMatch("0x00401000", "0x00402000");
|
runCorrelator(new SimilarSymbolNameProgramCorrelatorFactory());
|
||||||
checkAddressCorrelation(VTHashedFunctionAddressCorrelation.NAME);
|
selectMatch("0x00401000", "0x00402000");
|
||||||
checkCommentMarkup(EolCommentMarkupType.INSTANCE, "0x00401003", "Similar name eol comment.",
|
|
||||||
"NO_ADDRESS");
|
validateCommentMarkupItems(EolCommentMarkupType.INSTANCE, "0x00401003",
|
||||||
checkMarkupDestinationSource(VTHashedFunctionAddressCorrelation.NAME, true);
|
"Similar name eol comment.", "NO_ADDRESS");
|
||||||
|
validateMarkupDestinationAddress(VTHashedFunctionAddressCorrelation.NAME, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -193,23 +206,24 @@ public class AddressCorrelationTest extends AbstractGhidraHeadedIntegrationTest
|
||||||
// processors with matching instructions.
|
// processors with matching instructions.
|
||||||
Program p1 = buildProgram1("language1");
|
Program p1 = buildProgram1("language1");
|
||||||
Program p2 = buildProgram2("language2");
|
Program p2 = buildProgram2("language2");
|
||||||
|
|
||||||
createSession(p1, p2);
|
createSession(p1, p2);
|
||||||
vtTestEnv.showTool();
|
vtTestEnv.showTool();
|
||||||
addComment(CodeUnit.PLATE_COMMENT, "0x00401000", "First plate comment.");
|
addComment(CodeUnit.PLATE_COMMENT, "0x00401000", "First plate comment.");
|
||||||
addComment(CodeUnit.PLATE_COMMENT, "0x00401003", "Second plate comment.");
|
addComment(CodeUnit.PLATE_COMMENT, "0x00401003", "Second plate comment.");
|
||||||
addProgramCorrelation(new SimilarSymbolNameProgramCorrelatorFactory());
|
|
||||||
useMatch("0x00401000", "0x00402000");
|
runCorrelator(new SimilarSymbolNameProgramCorrelatorFactory());
|
||||||
checkAddressCorrelation(LinearFunctionAddressCorrelation.NAME);
|
selectMatch("0x00401000", "0x00402000");
|
||||||
|
|
||||||
// Verify the entry point plate comment markup has a destination address.
|
// Verify the entry point plate comment markup has a destination address.
|
||||||
checkCommentMarkup(PlateCommentMarkupType.INSTANCE, "0x00401000", "First plate comment.",
|
validateCommentMarkupItems(PlateCommentMarkupType.INSTANCE, "0x00401000",
|
||||||
"0x00402000");
|
"First plate comment.", "0x00402000");
|
||||||
assertEquals(addr("0x00402000", p2), getMatchingDestAddress("0x00401000")); // Expects a correlated address.
|
|
||||||
// Verify the non-entry point plate comment markup also has a destination address.
|
// The non-entry point plate comment markup has no address found when using the
|
||||||
checkCommentMarkup(PlateCommentMarkupType.INSTANCE, "0x00401003", "Second plate comment.",
|
// Code Compare correlators
|
||||||
"0x00402003");
|
validateCommentMarkupItems(PlateCommentMarkupType.INSTANCE, "0x00401003",
|
||||||
assertEquals(addr("0x00402003", p2), getMatchingDestAddress("0x00401003")); // Expects a correlated address.
|
"Second plate comment.", "NO_ADDRESS");
|
||||||
checkMarkupDestinationSource(LinearFunctionAddressCorrelation.NAME, true);
|
|
||||||
|
validateMarkupDestinationAddress(CodeCompareAddressCorrelation.NAME, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -219,53 +233,29 @@ public class AddressCorrelationTest extends AbstractGhidraHeadedIntegrationTest
|
||||||
// function entry point as the destination. This uses a function match created by
|
// function entry point as the destination. This uses a function match created by
|
||||||
// the Similar Symbol Name correlator where the two programs are for different
|
// the Similar Symbol Name correlator where the two programs are for different
|
||||||
// languages but the same processor with different instructions.
|
// languages but the same processor with different instructions.
|
||||||
Program languageProgram1 = buildProgram1("language1");
|
Program p1 = buildProgram1("language1");
|
||||||
Program languageProgram2 = buildProgram3("language3");
|
Program p2 = buildProgram3("language3");
|
||||||
|
createSession(p1, p2);
|
||||||
createSession(languageProgram1, languageProgram2);
|
|
||||||
vtTestEnv.showTool();
|
vtTestEnv.showTool();
|
||||||
addComment(CodeUnit.PLATE_COMMENT, "0x00401000", "First plate comment.");
|
addComment(CodeUnit.PLATE_COMMENT, "0x00401000", "First plate comment.");
|
||||||
addComment(CodeUnit.PLATE_COMMENT, "0x00401003", "Second plate comment.");
|
addComment(CodeUnit.PLATE_COMMENT, "0x00401003", "Second plate comment.");
|
||||||
addProgramCorrelation(new SimilarSymbolNameProgramCorrelatorFactory());
|
|
||||||
useMatch("0x00401000", "0x00402000");
|
runCorrelator(new SimilarSymbolNameProgramCorrelatorFactory());
|
||||||
checkAddressCorrelation(VTHashedFunctionAddressCorrelation.NAME);
|
selectMatch("0x00401000", "0x00402000");
|
||||||
|
|
||||||
// Verify the entry point plate comment markup has a destination address.
|
// Verify the entry point plate comment markup has a destination address.
|
||||||
checkCommentMarkup(PlateCommentMarkupType.INSTANCE, "0x00401000", "First plate comment.",
|
validateCommentMarkupItems(PlateCommentMarkupType.INSTANCE, "0x00401000",
|
||||||
"0x00402000");
|
"First plate comment.", "0x00402000");
|
||||||
assertNull(getMatchingDestAddress("0x00401000")); // Expects no correlated address.
|
|
||||||
// Verify the non-entry point plate comment markup does not have a destination address.
|
// Verify the non-entry point plate comment markup does not have a destination address.
|
||||||
checkCommentMarkup(PlateCommentMarkupType.INSTANCE, "0x00401003", "Second plate comment.",
|
validateCommentMarkupItems(PlateCommentMarkupType.INSTANCE, "0x00401003",
|
||||||
"NO_ADDRESS");
|
"Second plate comment.", "NO_ADDRESS");
|
||||||
assertNull(getMatchingDestAddress("0x00401003")); // Expects no correlated address.
|
validateMarkupDestinationAddress(VTHashedFunctionAddressCorrelation.NAME, true);
|
||||||
checkMarkupDestinationSource(VTHashedFunctionAddressCorrelation.NAME, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//==================================================================================================
|
//==================================================================================================
|
||||||
// Helper Methods
|
// Helper Methods
|
||||||
//==================================================================================================
|
//==================================================================================================
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the destination address that has been correlated to the indicated source address
|
|
||||||
* for the current function match that has been established in the test.
|
|
||||||
* @param srcAddressStr the source address
|
|
||||||
* @return the matching destination address. Otherwise null if the address correlation for
|
|
||||||
* the match couldn't determine a matching address.
|
|
||||||
*/
|
|
||||||
private Address getMatchingDestAddress(String srcAddressStr) {
|
|
||||||
Address srcAddress = addr(srcAddressStr, sourceProgram);
|
|
||||||
AddressCorrelation actualCorrelator =
|
|
||||||
controller.getCorrelator(sourceFunction, destinationFunction);
|
|
||||||
AddressRange destRange = null;
|
|
||||||
try {
|
|
||||||
destRange =
|
|
||||||
actualCorrelator.getCorrelatedDestinationRange(srcAddress, TaskMonitor.DUMMY);
|
|
||||||
}
|
|
||||||
catch (CancelledException e) {
|
|
||||||
// Do nothing. let this return null.
|
|
||||||
}
|
|
||||||
return (destRange != null) ? destRange.getMinAddress() : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Program buildProgram1(String name) throws Exception {
|
private Program buildProgram1(String name) throws Exception {
|
||||||
ProgramBuilder builder = new ProgramBuilder(name, ProgramBuilder._X86);
|
ProgramBuilder builder = new ProgramBuilder(name, ProgramBuilder._X86);
|
||||||
try {
|
try {
|
||||||
|
@ -357,7 +347,7 @@ public class AddressCorrelationTest extends AbstractGhidraHeadedIntegrationTest
|
||||||
* when creating matches.
|
* when creating matches.
|
||||||
* @param correlatorFactory the factory for the desired program correlator.
|
* @param correlatorFactory the factory for the desired program correlator.
|
||||||
*/
|
*/
|
||||||
protected void addProgramCorrelation(VTProgramCorrelatorFactory correlatorFactory) {
|
protected void runCorrelator(VTProgramCorrelatorFactory correlatorFactory) {
|
||||||
try {
|
try {
|
||||||
correlator = vtTestEnv.correlate(correlatorFactory, null, TaskMonitor.DUMMY);
|
correlator = vtTestEnv.correlate(correlatorFactory, null, TaskMonitor.DUMMY);
|
||||||
}
|
}
|
||||||
|
@ -374,22 +364,6 @@ public class AddressCorrelationTest extends AbstractGhidraHeadedIntegrationTest
|
||||||
Boolean.TRUE);
|
Boolean.TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks the address correlation being used for the current testMatch and its current
|
|
||||||
* sourceFunction and destinationFunction to verify it is the one indicated by the
|
|
||||||
* addressCorrelationName.
|
|
||||||
* @param addressCorrelationName the name of the expected address correlation for determining
|
|
||||||
* the destination address of markup for the current function match.
|
|
||||||
*/
|
|
||||||
private void checkAddressCorrelation(String addressCorrelationName) {
|
|
||||||
AddressCorrelation actualCorrelator =
|
|
||||||
controller.getCorrelator(sourceFunction, destinationFunction);
|
|
||||||
String actualCorrelatorName = actualCorrelator.getName();
|
|
||||||
assertTrue("Unexpected address correlation of " + actualCorrelatorName +
|
|
||||||
" when expecting " + addressCorrelationName + ".",
|
|
||||||
actualCorrelatorName.equals(addressCorrelationName));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks all the markup items for the testMatch to see that their destination address
|
* Checks all the markup items for the testMatch to see that their destination address
|
||||||
* has been determined by the address correlation that is indicated by the addressCorrelationName
|
* has been determined by the address correlation that is indicated by the addressCorrelationName
|
||||||
|
@ -397,7 +371,7 @@ public class AddressCorrelationTest extends AbstractGhidraHeadedIntegrationTest
|
||||||
* @param addressCorrelationName the name of the expected address correlation for determining
|
* @param addressCorrelationName the name of the expected address correlation for determining
|
||||||
* the destination address of non-function entry point markup items.
|
* the destination address of non-function entry point markup items.
|
||||||
*/
|
*/
|
||||||
private void checkMarkupDestinationSource(String addressCorrelationName,
|
private void validateMarkupDestinationAddress(String addressCorrelationName,
|
||||||
boolean canBeNoAddress) {
|
boolean canBeNoAddress) {
|
||||||
Collection<VTMarkupItem> appliableMarkupItems =
|
Collection<VTMarkupItem> appliableMarkupItems =
|
||||||
controller.getMatchInfo(testMatch).getAppliableMarkupItems(TaskMonitor.DUMMY); // Initialize the cache.
|
controller.getMatchInfo(testMatch).getAppliableMarkupItems(TaskMonitor.DUMMY); // Initialize the cache.
|
||||||
|
@ -430,7 +404,7 @@ public class AddressCorrelationTest extends AbstractGhidraHeadedIntegrationTest
|
||||||
* @param destination the destination address
|
* @param destination the destination address
|
||||||
* @return the match or null if the indicated match isn't found.
|
* @return the match or null if the indicated match isn't found.
|
||||||
*/
|
*/
|
||||||
protected VTMatch getMatch(Address source, Address destination) {
|
private VTMatch getMatch(Address source, Address destination) {
|
||||||
List<VTMatchSet> matchSets = session.getMatchSets();
|
List<VTMatchSet> matchSets = session.getMatchSets();
|
||||||
// Get matchSet 2 since 0 is manual matches and 1 is implied matches.
|
// Get matchSet 2 since 0 is manual matches and 1 is implied matches.
|
||||||
VTMatchSet vtMatchSet = matchSets.get(2);
|
VTMatchSet vtMatchSet = matchSets.get(2);
|
||||||
|
@ -448,7 +422,7 @@ public class AddressCorrelationTest extends AbstractGhidraHeadedIntegrationTest
|
||||||
* @param sourceAddressString the source address of the match's association.
|
* @param sourceAddressString the source address of the match's association.
|
||||||
* @param destinationAddressString the destination address of the match's association.
|
* @param destinationAddressString the destination address of the match's association.
|
||||||
*/
|
*/
|
||||||
protected void useMatch(String sourceAddressString, String destinationAddressString) {
|
private void selectMatch(String sourceAddressString, String destinationAddressString) {
|
||||||
sourceAddress = addr(sourceAddressString, sourceProgram);
|
sourceAddress = addr(sourceAddressString, sourceProgram);
|
||||||
destinationAddress = addr(destinationAddressString, destinationProgram);
|
destinationAddress = addr(destinationAddressString, destinationProgram);
|
||||||
|
|
||||||
|
@ -488,13 +462,13 @@ public class AddressCorrelationTest extends AbstractGhidraHeadedIntegrationTest
|
||||||
* @param desiredCommentMarkupType the comment markup type we are checking
|
* @param desiredCommentMarkupType the comment markup type we are checking
|
||||||
* @param sourceAddressString the source address of the markup
|
* @param sourceAddressString the source address of the markup
|
||||||
* @param comment the expected comment
|
* @param comment the expected comment
|
||||||
* @param destinationAddressString the expected destination address for the markup
|
* @param expectedDestAddrString the expected destination address for the markup
|
||||||
*/
|
*/
|
||||||
private void checkCommentMarkup(VTMarkupType desiredCommentMarkupType,
|
private void validateCommentMarkupItems(VTMarkupType desiredCommentMarkupType,
|
||||||
String sourceAddressString, String comment, String destinationAddressString) {
|
String sourceAddressString, String comment, String expectedDestAddrString) {
|
||||||
Address srcAddress = addr(sourceAddressString, sourceProgram);
|
Address srcAddress = addr(sourceAddressString, sourceProgram);
|
||||||
Address destAddress = destinationAddressString.equals("NO_ADDRESS") ? Address.NO_ADDRESS
|
Address expectedDestAddr = expectedDestAddrString.equals("NO_ADDRESS") ? Address.NO_ADDRESS
|
||||||
: addr(destinationAddressString, destinationProgram);
|
: addr(expectedDestAddrString, destinationProgram);
|
||||||
|
|
||||||
Collection<VTMarkupItem> appliableMarkupItems =
|
Collection<VTMarkupItem> appliableMarkupItems =
|
||||||
controller.getMatchInfo(testMatch).getAppliableMarkupItems(TaskMonitor.DUMMY); // Initialize the cache.
|
controller.getMatchInfo(testMatch).getAppliableMarkupItems(TaskMonitor.DUMMY); // Initialize the cache.
|
||||||
|
@ -521,18 +495,19 @@ public class AddressCorrelationTest extends AbstractGhidraHeadedIntegrationTest
|
||||||
}
|
}
|
||||||
boolean isNoAddress =
|
boolean isNoAddress =
|
||||||
markupDestAddress == null || markupDestAddress == Address.NO_ADDRESS;
|
markupDestAddress == null || markupDestAddress == Address.NO_ADDRESS;
|
||||||
if (destAddress == Address.NO_ADDRESS) {
|
if (expectedDestAddr == Address.NO_ADDRESS) {
|
||||||
assertTrue("Unexpected destination address of NO_ADDRESS for " +
|
assertTrue("Unexpected destination address of NO_ADDRESS for " +
|
||||||
vtMarkupItem.getMarkupType().getDisplayName() + " markup @ " +
|
vtMarkupItem.getMarkupType().getDisplayName() + " markup @ " +
|
||||||
vtMarkupItem.getSourceAddress().toString() + ".", isNoAddress);
|
vtMarkupItem.getSourceAddress().toString() + ".", isNoAddress);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
assertTrue(
|
assertTrue(
|
||||||
"Unexpected destination address of " + markupDestAddress.toString() +
|
"Unexpected destination address of " + markupDestAddress.toString() +
|
||||||
" when expecting " + destAddress.toString() + " for " +
|
" when expecting " + expectedDestAddr.toString() + " for " +
|
||||||
vtMarkupItem.getMarkupType().getDisplayName() + " markup @ " +
|
vtMarkupItem.getMarkupType().getDisplayName() + " markup @ " +
|
||||||
vtMarkupItem.getSourceAddress().toString() + ".",
|
vtMarkupItem.getSourceAddress().toString() + ".",
|
||||||
markupDestAddress.equals(destAddress));
|
markupDestAddress.equals(expectedDestAddr));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
/* ###
|
/* ###
|
||||||
* IP: GHIDRA
|
* IP: GHIDRA
|
||||||
* REVIEWED: YES
|
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -35,10 +34,10 @@ import ghidra.util.datastruct.LRUMap;
|
||||||
public class FixedSizeMRUCachingFactory<K, V> implements Factory<K, V> {
|
public class FixedSizeMRUCachingFactory<K, V> implements Factory<K, V> {
|
||||||
|
|
||||||
private LRUMap<K, V> cache;
|
private LRUMap<K, V> cache;
|
||||||
private Factory<K, V> delegate;
|
private Factory<K, V> factory;
|
||||||
|
|
||||||
public FixedSizeMRUCachingFactory(Factory<K, V> factory, int size) {
|
public FixedSizeMRUCachingFactory(Factory<K, V> factory, int size) {
|
||||||
this.delegate = factory;
|
this.factory = factory;
|
||||||
this.cache = new LRUMap<K, V>(size);
|
this.cache = new LRUMap<K, V>(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,7 +48,7 @@ public class FixedSizeMRUCachingFactory<K, V> implements Factory<K, V> {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
value = delegate.get(key);
|
value = factory.get(key);
|
||||||
cache.put(key, value);
|
cache.put(key, value);
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,6 @@
|
||||||
package ghidra.program.util;
|
package ghidra.program.util;
|
||||||
|
|
||||||
import ghidra.program.model.address.Address;
|
import ghidra.program.model.address.Address;
|
||||||
import ghidra.program.model.address.AddressRange;
|
|
||||||
import ghidra.util.exception.CancelledException;
|
import ghidra.util.exception.CancelledException;
|
||||||
import ghidra.util.task.TaskMonitor;
|
import ghidra.util.task.TaskMonitor;
|
||||||
|
|
||||||
|
@ -31,19 +30,20 @@ public interface AddressCorrelation {
|
||||||
* Returns the AddressRange of a set of addresses in the destination
|
* Returns the AddressRange of a set of addresses in the destination
|
||||||
* program that correlates to corresponding range in the source program.
|
* program that correlates to corresponding range in the source program.
|
||||||
*
|
*
|
||||||
* @param sourceAddress
|
* @param sourceAddress the source program address
|
||||||
* the source program address
|
|
||||||
* @param monitor the task monitor
|
* @param monitor the task monitor
|
||||||
* @return the destination program address range, or null if the source program address maps
|
* @return the destination program address range, or null if there is not address range mapped
|
||||||
* to one that is "deleted" in the destination program
|
|
||||||
* @throws CancelledException if cancelled
|
* @throws CancelledException if cancelled
|
||||||
*/
|
*/
|
||||||
public AddressRange getCorrelatedDestinationRange(Address sourceAddress, TaskMonitor monitor)
|
public AddressCorrelationRange getCorrelatedDestinationRange(Address sourceAddress,
|
||||||
throws CancelledException;
|
TaskMonitor monitor) throws CancelledException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the name of the correlating algorithm.
|
* This method is no longer part of the API. Leaving a default implementation to reduce
|
||||||
* @return the name of the correlating algorithm.
|
* breaking clients.
|
||||||
|
* @return the simple class name of the implementing class
|
||||||
*/
|
*/
|
||||||
public String getName();
|
public default String getName() {
|
||||||
|
return getClass().getSimpleName();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
/* ###
|
||||||
|
* 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.program.util;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import ghidra.program.model.address.Address;
|
||||||
|
import ghidra.program.model.address.AddressRange;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A simple object that holds an {@link AddressCorrelation} address range and then name of the
|
||||||
|
* correlation.s
|
||||||
|
*/
|
||||||
|
public class AddressCorrelationRange {
|
||||||
|
|
||||||
|
private AddressRange range;
|
||||||
|
private String correlatorName;
|
||||||
|
|
||||||
|
public AddressCorrelationRange(AddressRange range, String correlatorName) {
|
||||||
|
this.range = Objects.requireNonNull(range);
|
||||||
|
this.correlatorName = Objects.requireNonNull(correlatorName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Address getMinAddress() {
|
||||||
|
return range.getMinAddress();
|
||||||
|
}
|
||||||
|
|
||||||
|
public AddressRange getRange() {
|
||||||
|
return range;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCorrelatorName() {
|
||||||
|
return correlatorName;
|
||||||
|
}
|
||||||
|
}
|
|
@ -23,9 +23,34 @@ import ghidra.program.model.listing.Function;
|
||||||
/**
|
/**
|
||||||
* Interface for address correlation algorithms that can generate an address mapping from one
|
* Interface for address correlation algorithms that can generate an address mapping from one
|
||||||
* set of program addresses to another.
|
* set of program addresses to another.
|
||||||
|
* <p>
|
||||||
|
* This interface supplies a {@link #getPriority() priority} of {@link #DEFAULT_PRIORITY}.
|
||||||
|
* {@link DiscoverableAddressCorrelator discoverable} correlators can change this priority to be a
|
||||||
|
* lower value to be run before the supplied system correlators. Generally, the more specific or
|
||||||
|
* restrictive a correlator, the earlier (higher priority) it should be.
|
||||||
*/
|
*/
|
||||||
public interface AddressCorrelator {
|
public interface AddressCorrelator {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The default priority. This applies to client-supplied {@link DiscoverableAddressCorrelator}s
|
||||||
|
*/
|
||||||
|
public static final int DEFAULT_PRIORITY = 500;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A high priority (low number value) for correlators that should used before other correlators
|
||||||
|
*/
|
||||||
|
public static final int EARLY_PRIORITY = 100;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A low priority (high number value) for correlators that should used after other correlators
|
||||||
|
*/
|
||||||
|
public static final int LATE_CHANCE_PRIORITY = 1000;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A value used to raise or lower priorities.
|
||||||
|
*/
|
||||||
|
public static final int PRIORITY_OFFSET = 10;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an address mapping from one function to another.
|
* Returns an address mapping from one function to another.
|
||||||
* @param sourceFunction the source function.
|
* @param sourceFunction the source function.
|
||||||
|
@ -61,4 +86,18 @@ public interface AddressCorrelator {
|
||||||
* @return the options with the default settings for this correlator.
|
* @return the options with the default settings for this correlator.
|
||||||
*/
|
*/
|
||||||
public Options getDefaultOptions();
|
public Options getDefaultOptions();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a number based on an arbitrary number scheme that dictates the order that correlators
|
||||||
|
* should be used. If a correlator returns a null value from one of the {@code correlate()}
|
||||||
|
* methods, then the next highest priority correlator will be called, and so on until a non-null
|
||||||
|
* correlation is found or all correlators have been called.
|
||||||
|
* <p>
|
||||||
|
* A lower number value is a higher priority. See {@link #DEFAULT_PRIORITY}.
|
||||||
|
*
|
||||||
|
* @return the priority
|
||||||
|
*/
|
||||||
|
public default int getPriority() {
|
||||||
|
return DEFAULT_PRIORITY;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,8 @@
|
||||||
*/
|
*/
|
||||||
package ghidra.program.util;
|
package ghidra.program.util;
|
||||||
|
|
||||||
import ghidra.program.model.address.*;
|
import ghidra.program.model.address.Address;
|
||||||
|
import ghidra.program.model.address.AddressRangeImpl;
|
||||||
import ghidra.program.model.listing.Data;
|
import ghidra.program.model.listing.Data;
|
||||||
import ghidra.util.exception.CancelledException;
|
import ghidra.util.exception.CancelledException;
|
||||||
import ghidra.util.task.TaskMonitor;
|
import ghidra.util.task.TaskMonitor;
|
||||||
|
@ -30,13 +31,14 @@ public class LinearDataAddressCorrelation implements AddressCorrelation {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AddressRange getCorrelatedDestinationRange(Address sourceAddress, TaskMonitor monitor)
|
public AddressCorrelationRange getCorrelatedDestinationRange(Address sourceAddress,
|
||||||
throws CancelledException {
|
TaskMonitor monitor) throws CancelledException {
|
||||||
long offset = sourceAddress.getOffset();
|
long offset = sourceAddress.getOffset();
|
||||||
long base = sourceData.getAddress().getOffset();
|
long base = sourceData.getAddress().getOffset();
|
||||||
long delta = offset - base;
|
long delta = offset - base;
|
||||||
Address address = destinationData.getAddress().add(delta);
|
Address address = destinationData.getAddress().add(delta);
|
||||||
return new AddressRangeImpl(address, address);
|
AddressRangeImpl range = new AddressRangeImpl(address, address);
|
||||||
|
return new AddressCorrelationRange(range, getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -13,13 +13,13 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package ghidra.feature.vt.api.correlator.address;
|
package ghidra.program.util;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import ghidra.program.model.address.*;
|
import ghidra.program.model.address.*;
|
||||||
import ghidra.program.model.listing.*;
|
import ghidra.program.model.listing.*;
|
||||||
import ghidra.program.util.AddressCorrelation;
|
|
||||||
import ghidra.util.exception.CancelledException;
|
import ghidra.util.exception.CancelledException;
|
||||||
import ghidra.util.task.TaskMonitor;
|
import ghidra.util.task.TaskMonitor;
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ public class LinearFunctionAddressCorrelation implements AddressCorrelation {
|
||||||
private final Function sourceFunction;
|
private final Function sourceFunction;
|
||||||
private final Function destinationFunction;
|
private final Function destinationFunction;
|
||||||
|
|
||||||
LinearFunctionAddressCorrelation(Function sourceFunction, Function destinationFunction) {
|
public LinearFunctionAddressCorrelation(Function sourceFunction, Function destinationFunction) {
|
||||||
this.sourceFunction = sourceFunction;
|
this.sourceFunction = sourceFunction;
|
||||||
this.destinationFunction = destinationFunction;
|
this.destinationFunction = destinationFunction;
|
||||||
}
|
}
|
||||||
|
@ -42,8 +42,8 @@ public class LinearFunctionAddressCorrelation implements AddressCorrelation {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AddressRange getCorrelatedDestinationRange(Address sourceAddress, TaskMonitor monitor)
|
public AddressCorrelationRange getCorrelatedDestinationRange(Address sourceAddress,
|
||||||
throws CancelledException {
|
TaskMonitor monitor) throws CancelledException {
|
||||||
initialize(monitor);
|
initialize(monitor);
|
||||||
AddressRange toRange = cachedForwardAddressMap.get(sourceAddress);
|
AddressRange toRange = cachedForwardAddressMap.get(sourceAddress);
|
||||||
if (toRange == null) {
|
if (toRange == null) {
|
||||||
|
@ -51,7 +51,7 @@ public class LinearFunctionAddressCorrelation implements AddressCorrelation {
|
||||||
Address destinationAddress = getDestinationAddress(percentOffset);
|
Address destinationAddress = getDestinationAddress(percentOffset);
|
||||||
toRange = new AddressRangeImpl(destinationAddress, destinationAddress);
|
toRange = new AddressRangeImpl(destinationAddress, destinationAddress);
|
||||||
}
|
}
|
||||||
return toRange;
|
return new AddressCorrelationRange(toRange, getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initialize(TaskMonitor monitor) {
|
private void initialize(TaskMonitor monitor) {
|
||||||
|
@ -66,9 +66,7 @@ public class LinearFunctionAddressCorrelation implements AddressCorrelation {
|
||||||
|
|
||||||
long accumulatedLength = 0;
|
long accumulatedLength = 0;
|
||||||
|
|
||||||
Iterator<AddressRange> iterator = srcBody.iterator();
|
for (AddressRange range : srcBody) {
|
||||||
while (iterator.hasNext()) {
|
|
||||||
AddressRange range = iterator.next();
|
|
||||||
if (range.getMaxAddress().compareTo(address) < 0) {
|
if (range.getMaxAddress().compareTo(address) < 0) {
|
||||||
accumulatedLength += range.getLength();
|
accumulatedLength += range.getLength();
|
||||||
}
|
}
|
Loading…
Add table
Add a link
Reference in a new issue