mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-06-02 19:30:41 +08:00
GP-5996 - Version Tracking - Added option for apply function namespace
This commit is contained in:
+6
-6
@@ -261,27 +261,27 @@ public abstract class AbstractGhidraHeadlessIntegrationTest extends AbstractDock
|
|||||||
*
|
*
|
||||||
* @param <T> the return type
|
* @param <T> the return type
|
||||||
* @param <E> the exception type
|
* @param <E> the exception type
|
||||||
* @param p the program
|
* @param dobj the program or other domain object
|
||||||
* @param s the code to execute
|
* @param s the code to execute
|
||||||
* @return the supplier's return value
|
* @return the supplier's return value
|
||||||
* @see #modifyProgram(Program, ExceptionalCallback)
|
* @see #modifyProgram(Program, ExceptionalCallback)
|
||||||
* @see #modifyProgram(Program, ExceptionalFunction)
|
* @see #modifyProgram(Program, ExceptionalFunction)
|
||||||
*/
|
*/
|
||||||
public static <T, E extends Exception> T tx(Program p, ExceptionalSupplier<T, E> s) {
|
public static <T, E extends Exception> T tx(DomainObject dobj, ExceptionalSupplier<T, E> s) {
|
||||||
int txId = p.startTransaction("Test - Function in Transaction");
|
int txId = dobj.startTransaction("Test - Function in Transaction");
|
||||||
boolean commit = true;
|
boolean commit = true;
|
||||||
try {
|
try {
|
||||||
T t = s.get();
|
T t = s.get();
|
||||||
p.flushEvents();
|
dobj.flushEvents();
|
||||||
waitForSwing();
|
waitForSwing();
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
catch (Exception e) {
|
catch (Exception e) {
|
||||||
commit = false;
|
commit = false;
|
||||||
failWithException("Exception modifying program '" + p.getName() + "'", e);
|
failWithException("Exception modifying program '" + dobj.getName() + "'", e);
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
p.endTransaction(txId, commit);
|
dobj.endTransaction(txId, commit);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
BIN
Binary file not shown.
|
Before Width: | Height: | Size: 54 KiB After Width: | Height: | Size: 57 KiB |
+44
-15
@@ -164,13 +164,18 @@
|
|||||||
<ul>
|
<ul>
|
||||||
<li><b>Do Not Apply</b> - Do not apply markup to the destination program</li>
|
<li><b>Do Not Apply</b> - Do not apply markup to the destination program</li>
|
||||||
<li><b>Add</b> - Adds the function name from the source program to the one already
|
<li><b>Add</b> - Adds the function name from the source program to the one already
|
||||||
at the address in the destination program.</li>
|
at the address in the destination program. If the existing primary
|
||||||
|
symbol is default, then no new label will not be added, but instead
|
||||||
|
the existing label will be replaced with the source name.</li>
|
||||||
<li><b>Add As Primary</b> - Adds the function name from the source program to
|
<li><b>Add As Primary</b> - Adds the function name from the source program to
|
||||||
the one already at the address in the destination program. Sets the
|
the one already at the address in the destination program. Sets the
|
||||||
primary label in the destination program to whatever label was the
|
primary label in the destination program to whatever label was the
|
||||||
primary one in the source program.</li>
|
primary one in the source program. </li>
|
||||||
<li><b>Replace Always</b> - Always apply markup to from the source
|
<li><b>Replace Always</b> - Always use the source symbol name to replace
|
||||||
program to the destination program.</li>
|
the destination symbol name. The one exception is that if the
|
||||||
|
source symbol is a default symbol, then the destination symbol
|
||||||
|
name will be removed instead of being replaced with the source
|
||||||
|
symbol name.</li>
|
||||||
<li><b>Replace Default Only</b> - Only apply markup from the
|
<li><b>Replace Default Only</b> - Only apply markup from the
|
||||||
source program to the destination program when the label
|
source program to the destination program when the label
|
||||||
in the destination program is a default label.</li>
|
in the destination program is a default label.</li>
|
||||||
@@ -425,6 +430,40 @@
|
|||||||
</TD>
|
</TD>
|
||||||
</TR>
|
</TR>
|
||||||
|
|
||||||
|
|
||||||
|
<TR>
|
||||||
|
<TD><b>Function Signature</b> : <br>
|
||||||
|
Specifies the default action to take when applying the function
|
||||||
|
signature of a match.
|
||||||
|
</TD>
|
||||||
|
|
||||||
|
<TD nowrap><tt>Replace When Same Parameter Count</tt>
|
||||||
|
</TD>
|
||||||
|
</TR>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<TR>
|
||||||
|
<TD><b>Replace Namespace</b> : <br>
|
||||||
|
Specifies whether to apply the source function's namespace when applying
|
||||||
|
the function name.
|
||||||
|
|
||||||
|
<P>
|
||||||
|
<B>Note: If the source uses the Global namespace, then the destination
|
||||||
|
will not be updated when this option is on. The Global namespace is
|
||||||
|
considered the default namesapce. The assumption is that if the
|
||||||
|
destination program has a non-Global namespace, then the existing
|
||||||
|
destination namespace is preferred over the Global namespace.
|
||||||
|
</B>
|
||||||
|
</P>
|
||||||
|
</TD>
|
||||||
|
|
||||||
|
<TD nowrap><tt>False</tt>
|
||||||
|
</TD>
|
||||||
|
</TR>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<TR>
|
<TR>
|
||||||
<TD><b>Inline</b> : <br>
|
<TD><b>Inline</b> : <br>
|
||||||
Specifies the action to take for applying the inline flag when
|
Specifies the action to take for applying the inline flag when
|
||||||
@@ -497,17 +536,7 @@
|
|||||||
<TD nowrap><tt>False</tt>
|
<TD nowrap><tt>False</tt>
|
||||||
</TD>
|
</TD>
|
||||||
</TR>
|
</TR>
|
||||||
|
|
||||||
<TR>
|
|
||||||
<TD><b>Function Signature</b> : <br>
|
|
||||||
Specifies the default action to take when applying the function
|
|
||||||
signature of a match.
|
|
||||||
</TD>
|
|
||||||
|
|
||||||
<TD nowrap><tt>Replace When Same Parameter Count</tt>
|
|
||||||
</TD>
|
|
||||||
</TR>
|
|
||||||
|
|
||||||
<TR>
|
<TR>
|
||||||
<TD><b>Labels</b> : <br>
|
<TD><b>Labels</b> : <br>
|
||||||
Specifies the default action to take when applying the label of a match.
|
Specifies the default action to take when applying the label of a match.
|
||||||
|
|||||||
+25
-26
@@ -4,9 +4,9 @@
|
|||||||
* 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.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
@@ -115,33 +115,37 @@ public class MarkupItemImpl implements VTMarkupItem {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public VTMarkupType getMarkupType() {
|
public VTMarkupType getMarkupType() {
|
||||||
return markupItemStorage.getMarkupType();
|
return markupType;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public VTMarkupItemStatus getStatus() {
|
public VTMarkupItemStatus getStatus() {
|
||||||
validateDestinationCache();
|
validateDestinationCache();
|
||||||
VTMarkupItemStatus status = markupItemStorage.getStatus();
|
VTMarkupItemStatus status = markupItemStorage.getStatus();
|
||||||
if (status == UNAPPLIED) {
|
if (status != UNAPPLIED) {
|
||||||
if (!gettingStatus) {
|
return status;
|
||||||
try {
|
}
|
||||||
gettingStatus = true;
|
|
||||||
boolean conflictsWithOtherMarkup = getMarkupType().conflictsWithOtherMarkup(
|
if (!gettingStatus) {
|
||||||
this, getAssociation().getMarkupItems(TaskMonitor.DUMMY));
|
try {
|
||||||
if (conflictsWithOtherMarkup) {
|
gettingStatus = true;
|
||||||
return CONFLICT;
|
VTAssociation association = getAssociation();
|
||||||
}
|
Collection<VTMarkupItem> items = association.getMarkupItems(TaskMonitor.DUMMY);
|
||||||
}
|
boolean conflicts = markupType.conflictsWithOtherMarkup(this, items);
|
||||||
catch (CancelledException e) {
|
if (conflicts) {
|
||||||
// Shouldn't happen, but ignore if it does.
|
return CONFLICT;
|
||||||
}
|
|
||||||
finally {
|
|
||||||
gettingStatus = false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (hasSameSourceDestinationValues()) {
|
catch (CancelledException e) {
|
||||||
return SAME;
|
// Shouldn't happen, but ignore if it does.
|
||||||
}
|
}
|
||||||
|
finally {
|
||||||
|
gettingStatus = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasSameSourceDestinationValues()) {
|
||||||
|
return SAME;
|
||||||
}
|
}
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
@@ -196,15 +200,10 @@ public class MarkupItemImpl implements VTMarkupItem {
|
|||||||
markupItemStorage.setApplyFailed("Can't apply without a valid destination");
|
markupItemStorage.setApplyFailed("Can't apply without a valid destination");
|
||||||
fireMarkupItemStatusChanged(oldStatus, FAILED_APPLY);
|
fireMarkupItemStatusChanged(oldStatus, FAILED_APPLY);
|
||||||
throw new VersionTrackingApplyException(
|
throw new VersionTrackingApplyException(
|
||||||
"Cannot apply a markup item without first " + "setting the destination address");
|
"Cannot apply a markup item without first setting the destination address");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!canApply()) {
|
if (!canApply()) {
|
||||||
// TODO Should this throw an Exception instead?
|
|
||||||
// VTMarkupType itemMarkupType = item.getMarkupType();
|
|
||||||
// throw new VersionTrackingApplyException("Cannot apply " +
|
|
||||||
// itemMarkupType.getDisplayName() + " at " + item.getDestinationAddress().toString() +
|
|
||||||
// ".");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+250
-106
File diff suppressed because it is too large
Load Diff
+60
-37
@@ -1,13 +1,12 @@
|
|||||||
/* ###
|
/* ###
|
||||||
* 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.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
@@ -16,13 +15,19 @@
|
|||||||
*/
|
*/
|
||||||
package ghidra.feature.vt.api.markuptype;
|
package ghidra.feature.vt.api.markuptype;
|
||||||
|
|
||||||
|
import static ghidra.feature.vt.gui.util.VTOptionDefines.*;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
import ghidra.feature.vt.api.impl.MarkupItemImpl;
|
import ghidra.feature.vt.api.impl.MarkupItemImpl;
|
||||||
import ghidra.feature.vt.api.main.*;
|
import ghidra.feature.vt.api.main.*;
|
||||||
import ghidra.feature.vt.api.stringable.FunctionSignatureStringable;
|
import ghidra.feature.vt.api.stringable.FunctionSignatureStringable;
|
||||||
import ghidra.feature.vt.api.util.Stringable;
|
import ghidra.feature.vt.api.util.Stringable;
|
||||||
import ghidra.feature.vt.api.util.VersionTrackingApplyException;
|
import ghidra.feature.vt.api.util.VersionTrackingApplyException;
|
||||||
import ghidra.feature.vt.gui.util.*;
|
import ghidra.feature.vt.gui.plugin.VTController;
|
||||||
import ghidra.feature.vt.gui.util.VTMatchApplyChoices.FunctionSignatureChoices;
|
import ghidra.feature.vt.gui.util.VTMatchApplyChoices;
|
||||||
|
import ghidra.feature.vt.gui.util.VTMatchApplyChoices.*;
|
||||||
|
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;
|
||||||
@@ -30,16 +35,12 @@ import ghidra.program.model.listing.*;
|
|||||||
import ghidra.program.util.*;
|
import ghidra.program.util.*;
|
||||||
import ghidra.util.SystemUtilities;
|
import ghidra.util.SystemUtilities;
|
||||||
|
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
public class FunctionSignatureMarkupType extends FunctionEntryPointBasedAbstractMarkupType {
|
public class FunctionSignatureMarkupType extends FunctionEntryPointBasedAbstractMarkupType {
|
||||||
|
|
||||||
//==================================================================================================
|
//==================================================================================================
|
||||||
// Factory Methods
|
// Factory Methods
|
||||||
//==================================================================================================
|
//==================================================================================================
|
||||||
|
|
||||||
public static final VTMarkupType INSTANCE = new FunctionSignatureMarkupType();
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<VTMarkupItem> createMarkupItems(VTAssociation association) {
|
public List<VTMarkupItem> createMarkupItems(VTAssociation association) {
|
||||||
|
|
||||||
@@ -67,6 +68,10 @@ public class FunctionSignatureMarkupType extends FunctionEntryPointBasedAbstract
|
|||||||
// End Factory Methods
|
// End Factory Methods
|
||||||
//==================================================================================================
|
//==================================================================================================
|
||||||
|
|
||||||
|
public static final VTMarkupType INSTANCE = new FunctionSignatureMarkupType();
|
||||||
|
|
||||||
|
private ToolOptions unapplyOptions;
|
||||||
|
|
||||||
private FunctionSignatureMarkupType() {
|
private FunctionSignatureMarkupType() {
|
||||||
super("Function Signature");
|
super("Function Signature");
|
||||||
}
|
}
|
||||||
@@ -106,8 +111,42 @@ public class FunctionSignatureMarkupType extends FunctionEntryPointBasedAbstract
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
destinationSignatureStringable.applyFunctionSignature(destinationFunction,
|
ToolOptions options = getUnapplyOptions();
|
||||||
VT_UNAPPLY_MARKUP_OPTIONS, true);
|
destinationSignatureStringable.applyFunctionSignature(destinationFunction, options, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ToolOptions getUnapplyOptions() {
|
||||||
|
|
||||||
|
if (unapplyOptions != null) {
|
||||||
|
return unapplyOptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
unapplyOptions = new ToolOptions(VTController.VERSION_TRACKING_OPTIONS_NAME);
|
||||||
|
|
||||||
|
unapplyOptions.setEnum(FUNCTION_SIGNATURE, FunctionSignatureChoices.REPLACE);
|
||||||
|
unapplyOptions.setEnum(CALLING_CONVENTION, CallingConventionChoices.NAME_MATCH);
|
||||||
|
unapplyOptions.setEnum(INLINE, ReplaceChoices.REPLACE);
|
||||||
|
unapplyOptions.setEnum(NO_RETURN, ReplaceChoices.REPLACE);
|
||||||
|
unapplyOptions.setEnum(VAR_ARGS, ReplaceChoices.REPLACE);
|
||||||
|
unapplyOptions.setEnum(CALL_FIXUP, ReplaceChoices.REPLACE);
|
||||||
|
unapplyOptions.setEnum(FUNCTION_RETURN_TYPE, ParameterDataTypeChoices.REPLACE);
|
||||||
|
unapplyOptions.setEnum(PARAMETER_DATA_TYPES, ParameterDataTypeChoices.REPLACE);
|
||||||
|
unapplyOptions.setEnum(PARAMETER_NAMES, SourcePriorityChoices.REPLACE);
|
||||||
|
unapplyOptions.setEnum(PARAMETER_COMMENTS, CommentChoices.OVERWRITE_EXISTING);
|
||||||
|
|
||||||
|
unapplyOptions.setEnum(FUNCTION_NAME, FunctionNameChoices.REPLACE_ALWAYS);
|
||||||
|
unapplyOptions.setEnum(LABELS, LabelChoices.REPLACE_ALL);
|
||||||
|
|
||||||
|
unapplyOptions.setEnum(PLATE_COMMENT, CommentChoices.OVERWRITE_EXISTING);
|
||||||
|
unapplyOptions.setEnum(PRE_COMMENT, CommentChoices.OVERWRITE_EXISTING);
|
||||||
|
unapplyOptions.setEnum(END_OF_LINE_COMMENT, CommentChoices.OVERWRITE_EXISTING);
|
||||||
|
unapplyOptions.setEnum(REPEATABLE_COMMENT, CommentChoices.OVERWRITE_EXISTING);
|
||||||
|
unapplyOptions.setEnum(POST_COMMENT, CommentChoices.OVERWRITE_EXISTING);
|
||||||
|
|
||||||
|
unapplyOptions.setEnum(DATA_MATCH_DATA_TYPE,
|
||||||
|
ReplaceDataChoices.REPLACE_ALL_DATA);
|
||||||
|
|
||||||
|
return unapplyOptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -122,24 +161,6 @@ public class FunctionSignatureMarkupType extends FunctionEntryPointBasedAbstract
|
|||||||
markupItem.getMarkupType().getDisplayName() + " since it is excluded.");
|
markupItem.getMarkupType().getDisplayName() + " since it is excluded.");
|
||||||
}
|
}
|
||||||
|
|
||||||
ToolOptions adjustedOptions = markupOptions.copy();
|
|
||||||
// switch (functionSignatureChoice) {
|
|
||||||
// case REPLACE:
|
|
||||||
// adjustedOptions.putEnum(VTOptionDefines.FUNCTION_SIGNATURE,
|
|
||||||
// FunctionSignatureChoices.REPLACE);
|
|
||||||
// break;
|
|
||||||
// case WHEN_SAME_PARAMETER_COUNT:
|
|
||||||
// adjustedOptions.putEnum(VTOptionDefines.FUNCTION_SIGNATURE,
|
|
||||||
// FunctionSignatureChoices.WHEN_SAME_PARAMETER_COUNT);
|
|
||||||
// break;
|
|
||||||
// case WHEN_TAKING_SIGNATURE:
|
|
||||||
// // Don't apply the names. The function signature will do it if needed.
|
|
||||||
// return false;
|
|
||||||
// default:
|
|
||||||
// throw new IllegalArgumentException("Unsupported apply action: " + applyAction);
|
|
||||||
//
|
|
||||||
// }
|
|
||||||
|
|
||||||
Address destinationAddress = markupItem.getDestinationAddress();
|
Address destinationAddress = markupItem.getDestinationAddress();
|
||||||
|
|
||||||
if (destinationAddress == null) {
|
if (destinationAddress == null) {
|
||||||
@@ -147,7 +168,8 @@ public class FunctionSignatureMarkupType extends FunctionEntryPointBasedAbstract
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (destinationAddress == Address.NO_ADDRESS) {
|
if (destinationAddress == Address.NO_ADDRESS) {
|
||||||
throw new VersionTrackingApplyException("The destination address cannot be No Address!");
|
throw new VersionTrackingApplyException(
|
||||||
|
"The destination address cannot be No Address!");
|
||||||
}
|
}
|
||||||
|
|
||||||
Program destinationProgram = getDestinationProgram(markupItem.getAssociation());
|
Program destinationProgram = getDestinationProgram(markupItem.getAssociation());
|
||||||
@@ -166,11 +188,7 @@ public class FunctionSignatureMarkupType extends FunctionEntryPointBasedAbstract
|
|||||||
throw new VersionTrackingApplyException(
|
throw new VersionTrackingApplyException(
|
||||||
"Couldn't find destination function to apply a name.");
|
"Couldn't find destination function to apply a name.");
|
||||||
}
|
}
|
||||||
if (sourceStringable.applyFunctionSignature(destinationFunction, adjustedOptions, false)) {
|
if (sourceStringable.applyFunctionSignature(destinationFunction, markupOptions, false)) {
|
||||||
// // If the function signature was applied, apply the names if necessary.
|
|
||||||
// applyParameterNamesIfNeeded(markupItem, adjustedOptions);
|
|
||||||
// // If the function signature was applied, apply the no return flag if necessary.
|
|
||||||
// applyNoReturnIfNeeded(markupItem, adjustedOptions);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@@ -223,8 +241,9 @@ public class FunctionSignatureMarkupType extends FunctionEntryPointBasedAbstract
|
|||||||
}
|
}
|
||||||
Address entryAddress = function.getEntryPoint();
|
Address entryAddress = function.getEntryPoint();
|
||||||
Stringable value =
|
Stringable value =
|
||||||
isSource ? getSourceValue(association, address) : getCurrentDestinationValue(
|
isSource ? getSourceValue(association, address)
|
||||||
association, address);
|
: getCurrentDestinationValue(
|
||||||
|
association, address);
|
||||||
String displayString = (value != null) ? value.getDisplayString() : null;
|
String displayString = (value != null) ? value.getDisplayString() : null;
|
||||||
return new FunctionReturnTypeFieldLocation(program, entryAddress, displayString);
|
return new FunctionReturnTypeFieldLocation(program, entryAddress, displayString);
|
||||||
}
|
}
|
||||||
@@ -284,6 +303,10 @@ public class FunctionSignatureMarkupType extends FunctionEntryPointBasedAbstract
|
|||||||
options.setEnum(VTOptionDefines.FUNCTION_SIGNATURE,
|
options.setEnum(VTOptionDefines.FUNCTION_SIGNATURE,
|
||||||
FunctionSignatureChoices.REPLACE);
|
FunctionSignatureChoices.REPLACE);
|
||||||
break;
|
break;
|
||||||
|
case REPLACE_FIRST_ONLY:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return options;
|
return options;
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-33
@@ -4,9 +4,9 @@
|
|||||||
* 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.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
@@ -15,8 +15,6 @@
|
|||||||
*/
|
*/
|
||||||
package ghidra.feature.vt.api.markuptype;
|
package ghidra.feature.vt.api.markuptype;
|
||||||
|
|
||||||
import static ghidra.feature.vt.gui.util.VTOptionDefines.*;
|
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@@ -24,8 +22,6 @@ import ghidra.feature.vt.api.impl.MarkupItemImpl;
|
|||||||
import ghidra.feature.vt.api.main.*;
|
import ghidra.feature.vt.api.main.*;
|
||||||
import ghidra.feature.vt.api.util.Stringable;
|
import ghidra.feature.vt.api.util.Stringable;
|
||||||
import ghidra.feature.vt.api.util.VersionTrackingApplyException;
|
import ghidra.feature.vt.api.util.VersionTrackingApplyException;
|
||||||
import ghidra.feature.vt.gui.plugin.VTController;
|
|
||||||
import ghidra.feature.vt.gui.util.VTMatchApplyChoices.*;
|
|
||||||
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;
|
||||||
@@ -36,33 +32,6 @@ import ghidra.util.task.TaskMonitor;
|
|||||||
|
|
||||||
public abstract class VTMarkupType {
|
public abstract class VTMarkupType {
|
||||||
|
|
||||||
static final ToolOptions VT_UNAPPLY_MARKUP_OPTIONS =
|
|
||||||
new ToolOptions(VTController.VERSION_TRACKING_OPTIONS_NAME);
|
|
||||||
static {
|
|
||||||
VT_UNAPPLY_MARKUP_OPTIONS.setEnum(FUNCTION_SIGNATURE, FunctionSignatureChoices.REPLACE);
|
|
||||||
VT_UNAPPLY_MARKUP_OPTIONS.setEnum(CALLING_CONVENTION, CallingConventionChoices.NAME_MATCH);
|
|
||||||
VT_UNAPPLY_MARKUP_OPTIONS.setEnum(INLINE, ReplaceChoices.REPLACE);
|
|
||||||
VT_UNAPPLY_MARKUP_OPTIONS.setEnum(NO_RETURN, ReplaceChoices.REPLACE);
|
|
||||||
VT_UNAPPLY_MARKUP_OPTIONS.setEnum(VAR_ARGS, ReplaceChoices.REPLACE);
|
|
||||||
VT_UNAPPLY_MARKUP_OPTIONS.setEnum(CALL_FIXUP, ReplaceChoices.REPLACE);
|
|
||||||
VT_UNAPPLY_MARKUP_OPTIONS.setEnum(FUNCTION_RETURN_TYPE, ParameterDataTypeChoices.REPLACE);
|
|
||||||
VT_UNAPPLY_MARKUP_OPTIONS.setEnum(PARAMETER_DATA_TYPES, ParameterDataTypeChoices.REPLACE);
|
|
||||||
VT_UNAPPLY_MARKUP_OPTIONS.setEnum(PARAMETER_NAMES, SourcePriorityChoices.REPLACE);
|
|
||||||
VT_UNAPPLY_MARKUP_OPTIONS.setEnum(PARAMETER_COMMENTS, CommentChoices.OVERWRITE_EXISTING);
|
|
||||||
|
|
||||||
VT_UNAPPLY_MARKUP_OPTIONS.setEnum(FUNCTION_NAME, FunctionNameChoices.REPLACE_ALWAYS);
|
|
||||||
VT_UNAPPLY_MARKUP_OPTIONS.setEnum(LABELS, LabelChoices.REPLACE_ALL);
|
|
||||||
|
|
||||||
VT_UNAPPLY_MARKUP_OPTIONS.setEnum(PLATE_COMMENT, CommentChoices.OVERWRITE_EXISTING);
|
|
||||||
VT_UNAPPLY_MARKUP_OPTIONS.setEnum(PRE_COMMENT, CommentChoices.OVERWRITE_EXISTING);
|
|
||||||
VT_UNAPPLY_MARKUP_OPTIONS.setEnum(END_OF_LINE_COMMENT, CommentChoices.OVERWRITE_EXISTING);
|
|
||||||
VT_UNAPPLY_MARKUP_OPTIONS.setEnum(REPEATABLE_COMMENT, CommentChoices.OVERWRITE_EXISTING);
|
|
||||||
VT_UNAPPLY_MARKUP_OPTIONS.setEnum(POST_COMMENT, CommentChoices.OVERWRITE_EXISTING);
|
|
||||||
|
|
||||||
VT_UNAPPLY_MARKUP_OPTIONS.setEnum(DATA_MATCH_DATA_TYPE,
|
|
||||||
ReplaceDataChoices.REPLACE_ALL_DATA);
|
|
||||||
}
|
|
||||||
|
|
||||||
private final String name;
|
private final String name;
|
||||||
|
|
||||||
public VTMarkupType(String name) {
|
public VTMarkupType(String name) {
|
||||||
|
|||||||
+206
-61
@@ -4,9 +4,9 @@
|
|||||||
* 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.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
@@ -17,6 +17,7 @@ package ghidra.feature.vt.api.stringable;
|
|||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
|
import generic.json.Json;
|
||||||
import ghidra.app.cmd.label.SetLabelPrimaryCmd;
|
import ghidra.app.cmd.label.SetLabelPrimaryCmd;
|
||||||
import ghidra.app.util.NamespaceUtils;
|
import ghidra.app.util.NamespaceUtils;
|
||||||
import ghidra.feature.vt.api.util.Stringable;
|
import ghidra.feature.vt.api.util.Stringable;
|
||||||
@@ -45,8 +46,10 @@ public class FunctionNameStringable extends Stringable {
|
|||||||
if (symbol == null) {
|
if (symbol == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.symbolName = symbol.getName();
|
this.symbolName = symbol.getName();
|
||||||
this.sourceType = symbol.getSource();
|
this.sourceType = symbol.getSource();
|
||||||
|
|
||||||
Namespace namespace = symbol.getParentNamespace();
|
Namespace namespace = symbol.getParentNamespace();
|
||||||
while (namespace != null) {
|
while (namespace != null) {
|
||||||
if (namespace instanceof GlobalNamespace) {
|
if (namespace instanceof GlobalNamespace) {
|
||||||
@@ -84,11 +87,11 @@ public class FunctionNameStringable extends Stringable {
|
|||||||
sourceType = SourceType.valueOf(sourceName);
|
sourceType = SourceType.valueOf(sourceName);
|
||||||
|
|
||||||
while (tok.hasMoreTokens()) {
|
while (tok.hasMoreTokens()) {
|
||||||
getNamespaceInfo(tok);
|
addNamespaceInfo(tok);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void getNamespaceInfo(StringTokenizer tok) {
|
private void addNamespaceInfo(StringTokenizer tok) {
|
||||||
String name = tok.nextToken();
|
String name = tok.nextToken();
|
||||||
int id = Integer.parseInt(tok.nextToken());
|
int id = Integer.parseInt(tok.nextToken());
|
||||||
SymbolType type = SymbolType.getSymbolType(id);
|
SymbolType type = SymbolType.getSymbolType(id);
|
||||||
@@ -97,64 +100,187 @@ public class FunctionNameStringable extends Stringable {
|
|||||||
namespaceInfos.add(new NamespaceInfo(name, type, nameSpaceSourceType));
|
namespaceInfos.add(new NamespaceInfo(name, type, nameSpaceSourceType));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void applyFunctionName(Program program, Function function)
|
// Note: this is only meant to be called on the 'destination stringable'
|
||||||
|
public void unapplyFunctionNameAndNamespace(Function targetFunction)
|
||||||
throws DuplicateNameException, InvalidInputException, CircularDependencyException {
|
throws DuplicateNameException, InvalidInputException, CircularDependencyException {
|
||||||
|
|
||||||
Address entryPoint = function.getEntryPoint();
|
Namespace ns = createAllNamespacesAndClasses(targetFunction, namespaceInfos);
|
||||||
|
doApplyFunctionName(targetFunction, ns);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note: this is only meant to be called on the 'source stringable'
|
||||||
|
public void applyFunctionNameAndNamespace(Function targetFunction)
|
||||||
|
throws DuplicateNameException, InvalidInputException, CircularDependencyException {
|
||||||
|
|
||||||
|
// use this stringable's namespace info to create the equivalent namespace in the target
|
||||||
|
Namespace ns = createAllNamespacesAndClasses(targetFunction, namespaceInfos);
|
||||||
|
|
||||||
|
if (ns instanceof GlobalNamespace) {
|
||||||
|
Namespace targetNs = targetFunction.getParentNamespace();
|
||||||
|
if (!(targetNs instanceof GlobalNamespace)) {
|
||||||
|
// Assume for now that any non-global namespace in the target is preferred by the
|
||||||
|
// user to the default global namespace. We can always add another option for this
|
||||||
|
// behavior in the future. If we change this code, then update the help.
|
||||||
|
ns = targetNs;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
doApplyFunctionName(targetFunction, ns);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note: this is only meant to be called on the 'source stringable'
|
||||||
|
public void applyFunctionName(Function targetFunction)
|
||||||
|
throws DuplicateNameException, InvalidInputException, CircularDependencyException {
|
||||||
|
|
||||||
|
// apply only the name; keep the existing namespace
|
||||||
|
Symbol s = targetFunction.getSymbol();
|
||||||
|
Namespace ns = s.getParentNamespace();
|
||||||
|
doApplyFunctionName(targetFunction, ns);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void doApplyFunctionName(Function targetFunction, Namespace namespace)
|
||||||
|
throws DuplicateNameException, InvalidInputException, CircularDependencyException {
|
||||||
|
|
||||||
|
Symbol s = targetFunction.getSymbol();
|
||||||
|
Program targetProgram = targetFunction.getProgram();
|
||||||
|
SymbolTable symbolTable = targetProgram.getSymbolTable();
|
||||||
|
Address entryPoint = targetFunction.getEntryPoint();
|
||||||
if (entryPoint.isMemoryAddress() && sourceType == SourceType.DEFAULT) {
|
if (entryPoint.isMemoryAddress() && sourceType == SourceType.DEFAULT) {
|
||||||
// Apply a default name by removing the current one.
|
// Apply a default name by removing the current one.
|
||||||
program.getSymbolTable().removeSymbolSpecial(function.getSymbol());
|
symbolTable.removeSymbolSpecial(targetFunction.getSymbol());
|
||||||
|
s.setNamespace(namespace);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SymbolTable symbolTable = program.getSymbolTable();
|
|
||||||
Namespace namespace = program.getGlobalNamespace();
|
|
||||||
for (NamespaceInfo info : namespaceInfos) {
|
|
||||||
Namespace ns = symbolTable.getNamespace(info.name, namespace);
|
|
||||||
if (ns != null) {
|
|
||||||
if (function.isExternal() != ns.isExternal()) {
|
|
||||||
throw new DuplicateNameException("Conflicting namespace: " + info.name);
|
|
||||||
}
|
|
||||||
if (info.symbolType == SymbolType.CLASS &&
|
|
||||||
ns.getSymbol().getSymbolType() == SymbolType.NAMESPACE) {
|
|
||||||
// Promote existing namespace to class
|
|
||||||
ns = NamespaceUtils.convertNamespaceToClass(ns);
|
|
||||||
}
|
|
||||||
namespace = ns;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
namespace = createNamespace(program, info, namespace);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Symbol s = function.getSymbol();
|
|
||||||
s.setNameAndNamespace(symbolName, namespace, sourceType);
|
s.setNameAndNamespace(symbolName, namespace, sourceType);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addFunctionName(Program program, Function function, boolean isPrimary)
|
private Namespace createAllNamespacesAndClasses(Function destFunction,
|
||||||
|
List<NamespaceInfo> infos) throws DuplicateNameException, InvalidInputException {
|
||||||
|
|
||||||
|
Program destProgram = destFunction.getProgram();
|
||||||
|
SymbolTable symbolTable = destProgram.getSymbolTable();
|
||||||
|
Namespace namespace = destProgram.getGlobalNamespace();
|
||||||
|
for (NamespaceInfo info : infos) {
|
||||||
|
Namespace ns = symbolTable.getNamespace(info.name, namespace);
|
||||||
|
if (ns == null) {
|
||||||
|
namespace = createNamespace(destProgram, info, namespace);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (destFunction.isExternal() != ns.isExternal()) {
|
||||||
|
throw new DuplicateNameException("Conflicting namespace: " + info.name);
|
||||||
|
}
|
||||||
|
if (info.symbolType == SymbolType.CLASS &&
|
||||||
|
ns.getSymbol().getSymbolType() == SymbolType.NAMESPACE) {
|
||||||
|
// Promote existing namespace to class
|
||||||
|
ns = NamespaceUtils.convertNamespaceToClass(ns);
|
||||||
|
}
|
||||||
|
namespace = ns;
|
||||||
|
}
|
||||||
|
|
||||||
|
return namespace;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addFunctionNameAndNamespace(Function sourceFunction,
|
||||||
|
Function destFunction, boolean isPrimary)
|
||||||
throws DuplicateNameException, InvalidInputException, CircularDependencyException {
|
throws DuplicateNameException, InvalidInputException, CircularDependencyException {
|
||||||
|
|
||||||
|
List<NamespaceInfo> infos = new ArrayList<>();
|
||||||
|
Namespace namespace = sourceFunction.getParentNamespace();
|
||||||
|
while (namespace != null) {
|
||||||
|
if (namespace instanceof GlobalNamespace) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
infos.add(new NamespaceInfo(namespace));
|
||||||
|
namespace = namespace.getParentNamespace();
|
||||||
|
}
|
||||||
|
Collections.reverse(infos);
|
||||||
|
|
||||||
|
doAddFunctionName(destFunction, infos, isPrimary);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addFunctionName(Function destFunction, boolean isPrimary)
|
||||||
|
throws DuplicateNameException, InvalidInputException, CircularDependencyException {
|
||||||
|
|
||||||
|
doAddFunctionName(destFunction, List.of(), isPrimary);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void doAddFunctionName(Function destFunction, List<NamespaceInfo> namespaces,
|
||||||
|
boolean isPrimary)
|
||||||
|
throws DuplicateNameException, InvalidInputException, CircularDependencyException {
|
||||||
|
|
||||||
|
Program destProgram = destFunction.getProgram();
|
||||||
|
SymbolTable symbolTable = destProgram.getSymbolTable();
|
||||||
|
Namespace namespace = createAllNamespaces(destProgram, namespaces);
|
||||||
|
Symbol symbol = destFunction.getSymbol();
|
||||||
|
if (symbol.getSource() == SourceType.DEFAULT) {
|
||||||
|
// Special case: when the destination is default, replace the default symbol instead of
|
||||||
|
// adding a new symbol.
|
||||||
|
applyFunctionName(destFunction);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Address entryPoint = destFunction.getEntryPoint();
|
||||||
|
Symbol addedSymbol = symbolTable.createLabel(entryPoint, symbolName, namespace, sourceType);
|
||||||
|
if (!isPrimary || addedSymbol == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Address address = addedSymbol.getAddress();
|
||||||
|
String name = addedSymbol.getName();
|
||||||
|
Namespace ns = addedSymbol.getParentNamespace();
|
||||||
|
SetLabelPrimaryCmd cmd = new SetLabelPrimaryCmd(address, name, ns);
|
||||||
|
cmd.applyTo(destProgram);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSymbolNamespace() {
|
||||||
|
if (namespaceInfos.isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
StringBuilder buffy = new StringBuilder();
|
||||||
|
for (NamespaceInfo info : namespaceInfos) {
|
||||||
|
buffy.append(info.name).append(Namespace.DELIMITER);
|
||||||
|
}
|
||||||
|
|
||||||
|
int end = buffy.length();
|
||||||
|
int n = Namespace.DELIMITER.length();
|
||||||
|
buffy.delete(end - n, end);
|
||||||
|
return buffy.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSymbolName() {
|
||||||
|
return getSymbolName(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSymbolName(boolean includeNamespace) {
|
||||||
|
if (!includeNamespace) {
|
||||||
|
return symbolName;
|
||||||
|
}
|
||||||
|
|
||||||
|
StringBuilder buffy = new StringBuilder();
|
||||||
|
for (NamespaceInfo info : namespaceInfos) {
|
||||||
|
buffy.append(info.name).append(Namespace.DELIMITER);
|
||||||
|
}
|
||||||
|
buffy.append(symbolName);
|
||||||
|
return buffy.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public SourceType getSymbolSourceType() {
|
||||||
|
return sourceType;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Namespace createAllNamespaces(Program program, List<NamespaceInfo> namespaces)
|
||||||
|
throws DuplicateNameException, InvalidInputException {
|
||||||
|
|
||||||
SymbolTable symbolTable = program.getSymbolTable();
|
SymbolTable symbolTable = program.getSymbolTable();
|
||||||
Namespace namespace = program.getGlobalNamespace();
|
Namespace namespace = program.getGlobalNamespace();
|
||||||
for (NamespaceInfo info : namespaceInfos) {
|
for (NamespaceInfo info : namespaces) {
|
||||||
Namespace ns = symbolTable.getNamespace(info.name, namespace);
|
Namespace nextNs = symbolTable.getNamespace(info.name, namespace);
|
||||||
namespace = ns != null ? ns : createNamespace(program, info, namespace);
|
namespace = nextNs != null ? nextNs : createNamespace(program, info, namespace);
|
||||||
}
|
|
||||||
Symbol functionSymbol = function.getSymbol();
|
|
||||||
if (functionSymbol.getSource() == SourceType.DEFAULT) {
|
|
||||||
function.getSymbol().setNameAndNamespace(symbolName, namespace, sourceType);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// Add a label.
|
|
||||||
Symbol addedSymbol = symbolTable.createLabel(function.getEntryPoint(), symbolName,
|
|
||||||
namespace, sourceType);
|
|
||||||
if (isPrimary && addedSymbol != null) {
|
|
||||||
SetLabelPrimaryCmd setLabelPrimaryCmd =
|
|
||||||
new SetLabelPrimaryCmd(addedSymbol.getAddress(), addedSymbol.getName(),
|
|
||||||
addedSymbol.getParentNamespace());
|
|
||||||
setLabelPrimaryCmd.applyTo(program);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
return namespace;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Namespace createNamespace(Program program, NamespaceInfo info, Namespace namespace)
|
private Namespace createNamespace(Program program, NamespaceInfo info, Namespace namespace)
|
||||||
@@ -209,33 +335,52 @@ public class FunctionNameStringable extends Stringable {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//==================================================================================================
|
//==================================================================================================
|
||||||
// Inner Classes
|
// Inner Classes
|
||||||
//==================================================================================================
|
//==================================================================================================
|
||||||
private static class NamespaceInfo {
|
private static class NamespaceInfo {
|
||||||
String name;
|
|
||||||
SymbolType symbolType;
|
|
||||||
SourceType sourceType;
|
|
||||||
|
|
||||||
public NamespaceInfo(Namespace namespace) {
|
private String name;
|
||||||
|
private SymbolType symbolType;
|
||||||
|
private SourceType sourceType;
|
||||||
|
|
||||||
|
NamespaceInfo(Namespace namespace) {
|
||||||
this.name = namespace.getName();
|
this.name = namespace.getName();
|
||||||
this.symbolType = namespace.getSymbol().getSymbolType();
|
this.symbolType = namespace.getSymbol().getSymbolType();
|
||||||
this.sourceType = namespace.getSymbol().getSource();
|
this.sourceType = namespace.getSymbol().getSource();
|
||||||
}
|
}
|
||||||
|
|
||||||
public NamespaceInfo(String name, SymbolType type, SourceType sourceType) {
|
NamespaceInfo(String name, SymbolType type, SourceType sourceType) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.symbolType = type;
|
this.symbolType = type;
|
||||||
this.sourceType = sourceType;
|
this.sourceType = sourceType;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return Json.toString(this);
|
||||||
|
}
|
||||||
|
|
||||||
public String getSymbolName() {
|
@Override
|
||||||
return symbolName;
|
public int hashCode() {
|
||||||
}
|
return Objects.hash(name, sourceType, symbolType);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (obj == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (getClass() != obj.getClass()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
NamespaceInfo other = (NamespaceInfo) obj;
|
||||||
|
return Objects.equals(name, other.name) && sourceType == other.sourceType &&
|
||||||
|
Objects.equals(symbolType, other.symbolType);
|
||||||
|
}
|
||||||
|
|
||||||
public SourceType getSymbolSourceType() {
|
|
||||||
return sourceType;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+20
-47
@@ -19,7 +19,6 @@ import static ghidra.feature.vt.gui.util.VTOptionDefines.*;
|
|||||||
|
|
||||||
import java.awt.BorderLayout;
|
import java.awt.BorderLayout;
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
import java.awt.event.ActionListener;
|
|
||||||
import java.beans.PropertyChangeEvent;
|
import java.beans.PropertyChangeEvent;
|
||||||
import java.beans.PropertyChangeListener;
|
import java.beans.PropertyChangeListener;
|
||||||
|
|
||||||
@@ -59,6 +58,8 @@ public class ApplyMarkupPropertyEditor implements OptionsEditor {
|
|||||||
private static final String FUNCTION_SIGNATURE_TOOLTIP =
|
private static final String FUNCTION_SIGNATURE_TOOLTIP =
|
||||||
"<html>The apply action for the <b>function signature</b> " +
|
"<html>The apply action for the <b>function signature</b> " +
|
||||||
"when performing bulk apply operations</html>";
|
"when performing bulk apply operations</html>";
|
||||||
|
private static final String USE_NAMESPACE_TOOLTIP =
|
||||||
|
"<html>When true function namespaces will be applied when names are applied.";
|
||||||
private static final String PLATE_COMMENT_TOOLTIP =
|
private static final String PLATE_COMMENT_TOOLTIP =
|
||||||
"<html>The apply action for <b>plate comments</b> when performing bulk apply operations</html>";
|
"<html>The apply action for <b>plate comments</b> when performing bulk apply operations</html>";
|
||||||
private static final String PRE_COMMENT_TOOLTIP =
|
private static final String PRE_COMMENT_TOOLTIP =
|
||||||
@@ -119,6 +120,7 @@ public class ApplyMarkupPropertyEditor implements OptionsEditor {
|
|||||||
private JLabel dataMatchDataTypeLabel;
|
private JLabel dataMatchDataTypeLabel;
|
||||||
private JLabel functionNameLabel;
|
private JLabel functionNameLabel;
|
||||||
private JLabel functionSignatureLabel;
|
private JLabel functionSignatureLabel;
|
||||||
|
private JLabel useFunctionNamespaceLabel;
|
||||||
private JLabel returnTypeLabel;
|
private JLabel returnTypeLabel;
|
||||||
private JLabel inlineLabel;
|
private JLabel inlineLabel;
|
||||||
private JLabel noReturnLabel;
|
private JLabel noReturnLabel;
|
||||||
@@ -138,6 +140,7 @@ public class ApplyMarkupPropertyEditor implements OptionsEditor {
|
|||||||
private JComboBox<Enum<?>> dataMatchDataTypeComboBox;
|
private JComboBox<Enum<?>> dataMatchDataTypeComboBox;
|
||||||
private JComboBox<Enum<?>> functionNameComboBox;
|
private JComboBox<Enum<?>> functionNameComboBox;
|
||||||
private JComboBox<Enum<?>> functionSignatureComboBox;
|
private JComboBox<Enum<?>> functionSignatureComboBox;
|
||||||
|
private JCheckBox useFunctionNamespaceCheckBox;
|
||||||
private JComboBox<Enum<?>> returnTypeComboBox;
|
private JComboBox<Enum<?>> returnTypeComboBox;
|
||||||
private JComboBox<Enum<?>> callingConventionComboBox;
|
private JComboBox<Enum<?>> callingConventionComboBox;
|
||||||
private JComboBox<Enum<?>> inlineComboBox;
|
private JComboBox<Enum<?>> inlineComboBox;
|
||||||
@@ -160,8 +163,6 @@ public class ApplyMarkupPropertyEditor implements OptionsEditor {
|
|||||||
private JCheckBox ignoreExcludedCheckBox;
|
private JCheckBox ignoreExcludedCheckBox;
|
||||||
private JCheckBox ignoreIncompleteCheckBox;
|
private JCheckBox ignoreIncompleteCheckBox;
|
||||||
|
|
||||||
private ActionListener defaultActionListener;
|
|
||||||
|
|
||||||
private ToolOptions originalOptions;
|
private ToolOptions originalOptions;
|
||||||
private PropertyChangeListener listener;
|
private PropertyChangeListener listener;
|
||||||
private boolean unappliedChanges = false;
|
private boolean unappliedChanges = false;
|
||||||
@@ -206,7 +207,6 @@ public class ApplyMarkupPropertyEditor implements OptionsEditor {
|
|||||||
panel.add(createSeparator());
|
panel.add(createSeparator());
|
||||||
panel.add(createIgnoreCheckBoxPanel());
|
panel.add(createIgnoreCheckBoxPanel());
|
||||||
|
|
||||||
// TODO More needs to be done with the layout here.
|
|
||||||
panel.setBorder(BorderFactory.createTitledBorder("Apply Markup Options"));
|
panel.setBorder(BorderFactory.createTitledBorder("Apply Markup Options"));
|
||||||
JScrollPane scrollPane = new JScrollPane(panel);
|
JScrollPane scrollPane = new JScrollPane(panel);
|
||||||
|
|
||||||
@@ -223,7 +223,6 @@ public class ApplyMarkupPropertyEditor implements OptionsEditor {
|
|||||||
|
|
||||||
private Component createIgnoreCheckBoxPanel() {
|
private Component createIgnoreCheckBoxPanel() {
|
||||||
createIgnoreCheckBoxes();
|
createIgnoreCheckBoxes();
|
||||||
setupIgnoreMarkupItemsListeners();
|
|
||||||
|
|
||||||
JPanel panel = new JPanel();
|
JPanel panel = new JPanel();
|
||||||
panel.add(ignoreExcludedCheckBox);
|
panel.add(ignoreExcludedCheckBox);
|
||||||
@@ -239,16 +238,10 @@ public class ApplyMarkupPropertyEditor implements OptionsEditor {
|
|||||||
ignoreExcludedCheckBox.setToolTipText(IGNORE_EXCLUDED_TOOLTIP);
|
ignoreExcludedCheckBox.setToolTipText(IGNORE_EXCLUDED_TOOLTIP);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setupIgnoreMarkupItemsListeners() {
|
|
||||||
ignoreExcludedCheckBox.addActionListener(defaultActionListener);
|
|
||||||
ignoreIncompleteCheckBox.addActionListener(defaultActionListener);
|
|
||||||
}
|
|
||||||
|
|
||||||
private JPanel createFunctionSignatureSubPanel() {
|
private JPanel createFunctionSignatureSubPanel() {
|
||||||
|
|
||||||
createFunctionSignatureDetailLabels();
|
createFunctionSignatureDetailLabels();
|
||||||
createFunctionSignatureDetailChoices();
|
createFunctionSignatureDetailChoices();
|
||||||
setupFunctionSignatureDetailChoiceListeners();
|
|
||||||
|
|
||||||
JPanel outerPanel = new JPanel();
|
JPanel outerPanel = new JPanel();
|
||||||
outerPanel.setBorder(BorderFactory.createEmptyBorder(0, 3, 0, 0));
|
outerPanel.setBorder(BorderFactory.createEmptyBorder(0, 3, 0, 0));
|
||||||
@@ -325,19 +318,9 @@ public class ApplyMarkupPropertyEditor implements OptionsEditor {
|
|||||||
varArgsComboBox.setToolTipText(VAR_ARGS_TOOLTIP);
|
varArgsComboBox.setToolTipText(VAR_ARGS_TOOLTIP);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setupFunctionSignatureDetailChoiceListeners() {
|
|
||||||
returnTypeComboBox.addActionListener(defaultActionListener);
|
|
||||||
inlineComboBox.addActionListener(defaultActionListener);
|
|
||||||
noReturnComboBox.addActionListener(defaultActionListener);
|
|
||||||
callingConventionComboBox.addActionListener(defaultActionListener);
|
|
||||||
callFixupComboBox.addActionListener(defaultActionListener);
|
|
||||||
varArgsComboBox.addActionListener(defaultActionListener);
|
|
||||||
}
|
|
||||||
|
|
||||||
private JPanel createParametersSubPanel() {
|
private JPanel createParametersSubPanel() {
|
||||||
createParameterLabels();
|
createParameterLabels();
|
||||||
createParameterChoices();
|
createParameterChoices();
|
||||||
setupParameterChoiceListeners();
|
|
||||||
|
|
||||||
JPanel outerPanel = new JPanel();
|
JPanel outerPanel = new JPanel();
|
||||||
outerPanel.setBorder(BorderFactory.createEmptyBorder(0, 3, 0, 0));
|
outerPanel.setBorder(BorderFactory.createEmptyBorder(0, 3, 0, 0));
|
||||||
@@ -402,15 +385,6 @@ public class ApplyMarkupPropertyEditor implements OptionsEditor {
|
|||||||
PARAMETER_NAMES_REPLACE_IF_SAME_PRIORITY_TOOLTIP);
|
PARAMETER_NAMES_REPLACE_IF_SAME_PRIORITY_TOOLTIP);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setupParameterChoiceListeners() {
|
|
||||||
parameterDataTypesComboBox.addActionListener(defaultActionListener);
|
|
||||||
parameterNamesComboBox.addActionListener(defaultActionListener);
|
|
||||||
userHighestPriorityRB.addActionListener(defaultActionListener);
|
|
||||||
importHighestPriorityRB.addActionListener(defaultActionListener);
|
|
||||||
replaceIfSameSourceCheckBox.addActionListener(defaultActionListener);
|
|
||||||
parameterCommentsComboBox.addActionListener(defaultActionListener);
|
|
||||||
}
|
|
||||||
|
|
||||||
private JPanel createPrioritySubPanel() {
|
private JPanel createPrioritySubPanel() {
|
||||||
JPanel outerPanel = new JPanel();
|
JPanel outerPanel = new JPanel();
|
||||||
JPanel panel = new JPanel();
|
JPanel panel = new JPanel();
|
||||||
@@ -436,7 +410,6 @@ public class ApplyMarkupPropertyEditor implements OptionsEditor {
|
|||||||
|
|
||||||
createNonCommentMarkupLabels();
|
createNonCommentMarkupLabels();
|
||||||
createNonCommentMarkupChoices();
|
createNonCommentMarkupChoices();
|
||||||
setupNonCommentMarkupChoiceListeners();
|
|
||||||
|
|
||||||
JPanel outerPanel = new JPanel();
|
JPanel outerPanel = new JPanel();
|
||||||
outerPanel.setBorder(BorderFactory.createEmptyBorder(0, 3, 0, 0));
|
outerPanel.setBorder(BorderFactory.createEmptyBorder(0, 3, 0, 0));
|
||||||
@@ -452,6 +425,9 @@ public class ApplyMarkupPropertyEditor implements OptionsEditor {
|
|||||||
panel.add(functionSignatureLabel);
|
panel.add(functionSignatureLabel);
|
||||||
panel.add(functionSignatureComboBox);
|
panel.add(functionSignatureComboBox);
|
||||||
|
|
||||||
|
panel.add(useFunctionNamespaceLabel);
|
||||||
|
panel.add(useFunctionNamespaceCheckBox);
|
||||||
|
|
||||||
outerPanel.add(panel);
|
outerPanel.add(panel);
|
||||||
return outerPanel;
|
return outerPanel;
|
||||||
}
|
}
|
||||||
@@ -468,6 +444,9 @@ public class ApplyMarkupPropertyEditor implements OptionsEditor {
|
|||||||
|
|
||||||
functionSignatureLabel = new GDLabel("Function Signature", SwingConstants.RIGHT);
|
functionSignatureLabel = new GDLabel("Function Signature", SwingConstants.RIGHT);
|
||||||
functionSignatureLabel.setToolTipText(FUNCTION_SIGNATURE_TOOLTIP);
|
functionSignatureLabel.setToolTipText(FUNCTION_SIGNATURE_TOOLTIP);
|
||||||
|
|
||||||
|
useFunctionNamespaceLabel = new GDLabel("Replace Namespace", SwingConstants.RIGHT);
|
||||||
|
useFunctionNamespaceLabel.setToolTipText(USE_NAMESPACE_TOOLTIP);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createNonCommentMarkupChoices() {
|
private void createNonCommentMarkupChoices() {
|
||||||
@@ -485,19 +464,13 @@ public class ApplyMarkupPropertyEditor implements OptionsEditor {
|
|||||||
functionSignatureComboBox = createComboBox(VTOptionDefines.FUNCTION_SIGNATURE,
|
functionSignatureComboBox = createComboBox(VTOptionDefines.FUNCTION_SIGNATURE,
|
||||||
DEFAULT_OPTION_FOR_FUNCTION_SIGNATURE);
|
DEFAULT_OPTION_FOR_FUNCTION_SIGNATURE);
|
||||||
functionSignatureComboBox.setToolTipText(FUNCTION_SIGNATURE_TOOLTIP);
|
functionSignatureComboBox.setToolTipText(FUNCTION_SIGNATURE_TOOLTIP);
|
||||||
}
|
|
||||||
|
|
||||||
private void setupNonCommentMarkupChoiceListeners() {
|
useFunctionNamespaceCheckBox = createCheckBox("");
|
||||||
dataMatchDataTypeComboBox.addActionListener(defaultActionListener);
|
|
||||||
labelsComboBox.addActionListener(defaultActionListener);
|
|
||||||
functionNameComboBox.addActionListener(defaultActionListener);
|
|
||||||
functionSignatureComboBox.addActionListener(defaultActionListener);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private JPanel createCommentsSubPanel() {
|
private JPanel createCommentsSubPanel() {
|
||||||
createCommentLabels();
|
createCommentLabels();
|
||||||
createCommentChoices();
|
createCommentChoices();
|
||||||
setupCommentChoiceListeners();
|
|
||||||
|
|
||||||
JPanel outerPanel = new JPanel();
|
JPanel outerPanel = new JPanel();
|
||||||
outerPanel.setBorder(BorderFactory.createEmptyBorder(0, 3, 0, 0));
|
outerPanel.setBorder(BorderFactory.createEmptyBorder(0, 3, 0, 0));
|
||||||
@@ -562,14 +535,6 @@ public class ApplyMarkupPropertyEditor implements OptionsEditor {
|
|||||||
postCommentsComboBox.setToolTipText(POST_COMMENT_TOOLTIP);
|
postCommentsComboBox.setToolTipText(POST_COMMENT_TOOLTIP);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setupCommentChoiceListeners() {
|
|
||||||
plateCommentsComboBox.addActionListener(defaultActionListener);
|
|
||||||
preCommentsComboBox.addActionListener(defaultActionListener);
|
|
||||||
endOfLineCommentsComboBox.addActionListener(defaultActionListener);
|
|
||||||
repeatableCommentsComboBox.addActionListener(defaultActionListener);
|
|
||||||
postCommentsComboBox.addActionListener(defaultActionListener);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateOptions(ToolOptions options) {
|
private void updateOptions(ToolOptions options) {
|
||||||
updateNonCommentMarkupOptions(options);
|
updateNonCommentMarkupOptions(options);
|
||||||
updateCommentOptions(options);
|
updateCommentOptions(options);
|
||||||
@@ -594,6 +559,9 @@ public class ApplyMarkupPropertyEditor implements OptionsEditor {
|
|||||||
FunctionSignatureChoices functionSignatureChoice =
|
FunctionSignatureChoices functionSignatureChoice =
|
||||||
(FunctionSignatureChoices) functionSignatureComboBox.getSelectedItem();
|
(FunctionSignatureChoices) functionSignatureComboBox.getSelectedItem();
|
||||||
options.setEnum(FUNCTION_SIGNATURE, functionSignatureChoice);
|
options.setEnum(FUNCTION_SIGNATURE, functionSignatureChoice);
|
||||||
|
|
||||||
|
boolean useNamespaces = useFunctionNamespaceCheckBox.isSelected();
|
||||||
|
options.setBoolean(USE_NAMESPACE_FUNCTIONS, useNamespaces);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateCommentOptions(ToolOptions options) {
|
private void updateCommentOptions(ToolOptions options) {
|
||||||
@@ -704,6 +672,12 @@ public class ApplyMarkupPropertyEditor implements OptionsEditor {
|
|||||||
if (functionSignatureChoice != functionSignatureComboBox.getSelectedItem()) {
|
if (functionSignatureChoice != functionSignatureComboBox.getSelectedItem()) {
|
||||||
functionSignatureComboBox.setSelectedItem(functionSignatureChoice);
|
functionSignatureComboBox.setSelectedItem(functionSignatureChoice);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean useNamespace =
|
||||||
|
options.getBoolean(USE_NAMESPACE_FUNCTIONS, DEFAULT_OPTION_FOR_NAMESPACE_FUNCTIONS);
|
||||||
|
if (useFunctionNamespaceCheckBox.isSelected() != useNamespace) {
|
||||||
|
useFunctionNamespaceCheckBox.setSelected(useNamespace);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setEditorCommentValues(ToolOptions options) {
|
private void setEditorCommentValues(ToolOptions options) {
|
||||||
@@ -852,7 +826,6 @@ public class ApplyMarkupPropertyEditor implements OptionsEditor {
|
|||||||
|
|
||||||
// signals that there are unapplied changes
|
// signals that there are unapplied changes
|
||||||
private void changesMade(boolean changes) {
|
private void changesMade(boolean changes) {
|
||||||
// FIXME Is this ok? complete?
|
|
||||||
if (listener != null) {
|
if (listener != null) {
|
||||||
listener.propertyChange(new PropertyChangeEvent(this, GhidraOptions.APPLY_ENABLED,
|
listener.propertyChange(new PropertyChangeEvent(this, GhidraOptions.APPLY_ENABLED,
|
||||||
unappliedChanges, changes));
|
unappliedChanges, changes));
|
||||||
|
|||||||
+3
@@ -766,6 +766,9 @@ public class VTMatchTableProvider extends ComponentProviderAdapter
|
|||||||
"Markup items that are incomplete (for example, no destination address is specified) " +
|
"Markup items that are incomplete (for example, no destination address is specified) " +
|
||||||
"should become ignored by applying a match.");
|
"should become ignored by applying a match.");
|
||||||
|
|
||||||
|
vtOptions.registerOption(USE_NAMESPACE_FUNCTIONS, DEFAULT_OPTION_FOR_NAMESPACE_FUNCTIONS,
|
||||||
|
null, "Apply the non-Global source namespace to the destination function.");
|
||||||
|
|
||||||
vtOptions.getOptions(APPLY_MARKUP_OPTIONS_NAME)
|
vtOptions.getOptions(APPLY_MARKUP_OPTIONS_NAME)
|
||||||
.registerOptionsEditor(() -> new ApplyMarkupPropertyEditor(controller));
|
.registerOptionsEditor(() -> new ApplyMarkupPropertyEditor(controller));
|
||||||
vtOptions.getOptions(DISPLAY_APPLY_MARKUP_OPTIONS)
|
vtOptions.getOptions(DISPLAY_APPLY_MARKUP_OPTIONS)
|
||||||
|
|||||||
+6
-1
@@ -68,6 +68,8 @@ public class VTOptionDefines {
|
|||||||
public static CommentChoices DEFAULT_OPTION_FOR_POST_COMMENTS =
|
public static CommentChoices DEFAULT_OPTION_FOR_POST_COMMENTS =
|
||||||
CommentChoices.APPEND_TO_EXISTING;
|
CommentChoices.APPEND_TO_EXISTING;
|
||||||
|
|
||||||
|
public static boolean DEFAULT_OPTION_FOR_NAMESPACE_FUNCTIONS = false;
|
||||||
|
|
||||||
public static final String FUNCTION_NAME = APPLY_MARKUP_OPTIONS_NAME + ".Function Name";
|
public static final String FUNCTION_NAME = APPLY_MARKUP_OPTIONS_NAME + ".Function Name";
|
||||||
public static final String FUNCTION_RETURN_TYPE = APPLY_MARKUP_OPTIONS_NAME +
|
public static final String FUNCTION_RETURN_TYPE = APPLY_MARKUP_OPTIONS_NAME +
|
||||||
".Function Return Type";
|
".Function Return Type";
|
||||||
@@ -105,9 +107,12 @@ public class VTOptionDefines {
|
|||||||
public static final String IGNORE_EXCLUDED_MARKUP_ITEMS = APPLY_MARKUP_OPTIONS_NAME +
|
public static final String IGNORE_EXCLUDED_MARKUP_ITEMS = APPLY_MARKUP_OPTIONS_NAME +
|
||||||
".Set Excluded Markup Items To Ignored";
|
".Set Excluded Markup Items To Ignored";
|
||||||
|
|
||||||
public final static String DISPLAY_APPLY_MARKUP_OPTIONS = APPLY_MARKUP_OPTIONS_NAME +
|
public static final String DISPLAY_APPLY_MARKUP_OPTIONS = APPLY_MARKUP_OPTIONS_NAME +
|
||||||
Options.DELIMITER + "Display Apply Markup Options";
|
Options.DELIMITER + "Display Apply Markup Options";
|
||||||
|
|
||||||
|
public static final String USE_NAMESPACE_FUNCTIONS =
|
||||||
|
APPLY_MARKUP_OPTIONS_NAME + ".Replace Namespace";
|
||||||
|
|
||||||
// Auto VT Options
|
// Auto VT Options
|
||||||
public static final String AUTO_VT_OPTIONS_NAME = "Auto Version Tracking Options";
|
public static final String AUTO_VT_OPTIONS_NAME = "Auto Version Tracking Options";
|
||||||
|
|
||||||
|
|||||||
+1204
File diff suppressed because it is too large
Load Diff
+264
-191
File diff suppressed because it is too large
Load Diff
+46
-10
@@ -4,9 +4,9 @@
|
|||||||
* 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.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
@@ -35,6 +35,7 @@ import ghidra.program.database.ProgramDB;
|
|||||||
import ghidra.program.model.address.Address;
|
import ghidra.program.model.address.Address;
|
||||||
import ghidra.program.model.address.AddressSet;
|
import ghidra.program.model.address.AddressSet;
|
||||||
import ghidra.test.*;
|
import ghidra.test.*;
|
||||||
|
import ghidra.util.Msg;
|
||||||
import ghidra.util.task.TaskMonitor;
|
import ghidra.util.task.TaskMonitor;
|
||||||
|
|
||||||
public abstract class AbstractVTMarkupItemTest extends AbstractGhidraHeadedIntegrationTest {
|
public abstract class AbstractVTMarkupItemTest extends AbstractGhidraHeadedIntegrationTest {
|
||||||
@@ -55,6 +56,10 @@ public abstract class AbstractVTMarkupItemTest extends AbstractGhidraHeadedInteg
|
|||||||
env = new TestEnv();
|
env = new TestEnv();
|
||||||
setErrorGUIEnabled(false);
|
setErrorGUIEnabled(false);
|
||||||
|
|
||||||
|
resetPrograms();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void resetPrograms() throws Exception {
|
||||||
sourceBuilder = new ClassicSampleX86ProgramBuilder("notepadSrc", true, this);
|
sourceBuilder = new ClassicSampleX86ProgramBuilder("notepadSrc", true, this);
|
||||||
sourceProgram = sourceBuilder.getProgram();
|
sourceProgram = sourceBuilder.getProgram();
|
||||||
|
|
||||||
@@ -112,6 +117,8 @@ public abstract class AbstractVTMarkupItemTest extends AbstractGhidraHeadedInteg
|
|||||||
*/
|
*/
|
||||||
protected abstract class TestDataProviderAndValidator {
|
protected abstract class TestDataProviderAndValidator {
|
||||||
|
|
||||||
|
protected ToolOptions options;
|
||||||
|
|
||||||
protected abstract Address getSourceMatchAddress();
|
protected abstract Address getSourceMatchAddress();
|
||||||
|
|
||||||
protected abstract Address getDestinationMatchAddress();
|
protected abstract Address getDestinationMatchAddress();
|
||||||
@@ -134,6 +141,11 @@ public abstract class AbstractVTMarkupItemTest extends AbstractGhidraHeadedInteg
|
|||||||
* @return the Apply Markup Options for the validator to use.
|
* @return the Apply Markup Options for the validator to use.
|
||||||
*/
|
*/
|
||||||
protected ToolOptions getOptions() {
|
protected ToolOptions getOptions() {
|
||||||
|
|
||||||
|
if (options != null) {
|
||||||
|
return options;
|
||||||
|
}
|
||||||
|
|
||||||
ToolOptions applyOptions = new ToolOptions(VERSION_TRACKING_OPTIONS_NAME);
|
ToolOptions applyOptions = new ToolOptions(VERSION_TRACKING_OPTIONS_NAME);
|
||||||
|
|
||||||
applyOptions.setEnum(FUNCTION_NAME, FunctionNameChoices.REPLACE_ALWAYS);
|
applyOptions.setEnum(FUNCTION_NAME, FunctionNameChoices.REPLACE_ALWAYS);
|
||||||
@@ -165,10 +177,29 @@ public abstract class AbstractVTMarkupItemTest extends AbstractGhidraHeadedInteg
|
|||||||
|
|
||||||
applyOptions.setEnum(DATA_MATCH_DATA_TYPE,
|
applyOptions.setEnum(DATA_MATCH_DATA_TYPE,
|
||||||
ReplaceDataChoices.REPLACE_UNDEFINED_DATA_ONLY);
|
ReplaceDataChoices.REPLACE_UNDEFINED_DATA_ONLY);
|
||||||
|
|
||||||
|
options = applyOptions;
|
||||||
return applyOptions;
|
return applyOptions;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void doTestFindButCannotApplyMarkupItem_SameStatus(
|
||||||
|
TestDataProviderAndValidator validator) throws Exception {
|
||||||
|
|
||||||
|
VTSessionDB session = createNewSession();
|
||||||
|
VTMatch match = createMatchSetWithOneMatch(session, validator.getSourceMatchAddress(),
|
||||||
|
validator.getDestinationMatchAddress());
|
||||||
|
VTMarkupItem markupItem = validator.searchForMarkupItem(match);
|
||||||
|
|
||||||
|
List<VTMarkupItem> markupItems = new ArrayList<>();
|
||||||
|
Address destinationApplyAddress = validator.getDestinationApplyAddress();
|
||||||
|
markupItem.setDefaultDestinationAddress(destinationApplyAddress, TEST_ADDRESS_SOURCE);
|
||||||
|
markupItems.add(markupItem);
|
||||||
|
|
||||||
|
VTMarkupItemStatus status = markupItem.getStatus();
|
||||||
|
assertEquals(VTMarkupItemStatus.SAME, status);
|
||||||
|
}
|
||||||
|
|
||||||
protected void doTestFindAndApplyMarkupItem(TestDataProviderAndValidator validator)
|
protected void doTestFindAndApplyMarkupItem(TestDataProviderAndValidator validator)
|
||||||
throws Exception {
|
throws Exception {
|
||||||
|
|
||||||
@@ -319,7 +350,10 @@ public abstract class AbstractVTMarkupItemTest extends AbstractGhidraHeadedInteg
|
|||||||
// verify that calling apply still leaves us in an unapplied state
|
// verify that calling apply still leaves us in an unapplied state
|
||||||
//
|
//
|
||||||
task = new ApplyMarkupItemTask(session, markupItems, validator.getOptions());
|
task = new ApplyMarkupItemTask(session, markupItems, validator.getOptions());
|
||||||
|
|
||||||
|
setErrorsExpected(true);
|
||||||
runTask(session, task);
|
runTask(session, task);
|
||||||
|
setErrorsExpected(false);
|
||||||
|
|
||||||
assertEquals("The markup item status was not correctly set",
|
assertEquals("The markup item status was not correctly set",
|
||||||
VTMarkupItemStatus.FAILED_APPLY, markupItem.getStatus());
|
VTMarkupItemStatus.FAILED_APPLY, markupItem.getStatus());
|
||||||
@@ -354,9 +388,8 @@ public abstract class AbstractVTMarkupItemTest extends AbstractGhidraHeadedInteg
|
|||||||
|
|
||||||
protected static VTMatch createMatchSetWithOneMatch(VTSessionDB db, Address sourceAddress,
|
protected static VTMatch createMatchSetWithOneMatch(VTSessionDB db, Address sourceAddress,
|
||||||
Address destinationAddress) throws Exception {
|
Address destinationAddress) throws Exception {
|
||||||
int testTransactionID = 0;
|
|
||||||
try {
|
return tx(db, () -> {
|
||||||
testTransactionID = db.startTransaction("Test Match Set Setup");
|
|
||||||
VTMatchInfo matchInfo = createRandomMatch(sourceAddress, destinationAddress, db);
|
VTMatchInfo matchInfo = createRandomMatch(sourceAddress, destinationAddress, db);
|
||||||
VTMatchSet matchSet = db.createMatchSet(
|
VTMatchSet matchSet = db.createMatchSet(
|
||||||
createProgramCorrelator(db.getSourceProgram(), db.getDestinationProgram()));
|
createProgramCorrelator(db.getSourceProgram(), db.getDestinationProgram()));
|
||||||
@@ -368,19 +401,22 @@ public abstract class AbstractVTMarkupItemTest extends AbstractGhidraHeadedInteg
|
|||||||
association.getMarkupItems(TaskMonitor.DUMMY);
|
association.getMarkupItems(TaskMonitor.DUMMY);
|
||||||
|
|
||||||
return addedMatch;
|
return addedMatch;
|
||||||
}
|
});
|
||||||
finally {
|
|
||||||
db.endTransaction(testTransactionID, true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void runTask(VTSession session, VtTask task) {
|
protected void runTask(VTSession session, VtTask task) {
|
||||||
int id = session.startTransaction("test");
|
int id = session.startTransaction("test");
|
||||||
try {
|
try {
|
||||||
task.run(TaskMonitor.DUMMY);
|
task.run(TaskMonitor.DUMMY);
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
session.endTransaction(id, true);
|
session.endTransaction(id, true);
|
||||||
|
|
||||||
|
if (task.hasErrors()) {
|
||||||
|
String errorDetails = task.getErrorDetails();
|
||||||
|
Msg.error(this, "Error applying task: " + errorDetails);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+1
@@ -96,6 +96,7 @@ public class VersionControlScreenShots extends GhidraScreenShotGenerator {
|
|||||||
|
|
||||||
UndoActionDialog d = waitForDialogComponent(UndoActionDialog.class);
|
UndoActionDialog d = waitForDialogComponent(UndoActionDialog.class);
|
||||||
captureDialog(d);
|
captureDialog(d);
|
||||||
|
|
||||||
close(d);
|
close(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user