mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-01-10 06:27:59 -05:00
Merge remote-tracking branch 'origin/GP-1430-dragonmacher-symbol-table-set-namespace--SQUASHED'
This commit is contained in:
@@ -32,30 +32,25 @@ public class AutoRenameLabelsScript extends GhidraScript {
|
||||
return;
|
||||
}
|
||||
|
||||
String base = askString("Auto Rename Labels", "Enter label base name:");
|
||||
if (base == null) {
|
||||
println("No base value entered.");
|
||||
String baseName = askString("Auto Rename Labels", "Enter label name prefix:");
|
||||
if (baseName == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
int num = 1;
|
||||
|
||||
AddressSetView view = currentSelection;
|
||||
if ((view == null) || (view.isEmpty()))
|
||||
if ((view == null) || (view.isEmpty())) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Obtain the symbol table and listing from program
|
||||
SymbolTable symbolTable = currentProgram.getSymbolTable();
|
||||
|
||||
// Get the addresses in the set.
|
||||
AddressIterator it = view.getAddresses(true);
|
||||
|
||||
CompoundCmd cmd = new CompoundCmd("Auto Rename Labels");
|
||||
while (it.hasNext()) {
|
||||
Address address = it.next();
|
||||
Symbol primary = symbolTable.getPrimarySymbol(address);
|
||||
if (primary != null && primary.getSource() == SourceType.DEFAULT) {
|
||||
cmd.add(new RenameLabelCmd(address, null, base + num++, SourceType.USER_DEFINED));
|
||||
cmd.add(new RenameLabelCmd(primary, baseName + num++, SourceType.USER_DEFINED));
|
||||
}
|
||||
}
|
||||
if (cmd.size() > 0) {
|
||||
|
||||
@@ -15,6 +15,12 @@
|
||||
*/
|
||||
package ghidra.app.cmd.label;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import ghidra.app.util.NamespaceUtils;
|
||||
import ghidra.app.util.SymbolPath;
|
||||
import ghidra.framework.cmd.Command;
|
||||
import ghidra.framework.model.DomainObject;
|
||||
import ghidra.program.model.address.Address;
|
||||
@@ -25,92 +31,119 @@ import ghidra.util.exception.DuplicateNameException;
|
||||
import ghidra.util.exception.InvalidInputException;
|
||||
|
||||
/**
|
||||
* Command for renaming labels. Handles converting back and forth between
|
||||
* default and named labels as well.
|
||||
* Command for renaming labels. Handles converting back and forth between default and named labels
|
||||
* as well.
|
||||
*/
|
||||
public class RenameLabelCmd implements Command {
|
||||
|
||||
private Address addr;
|
||||
private String oldName;
|
||||
private String newName;
|
||||
private Symbol existingSymbol;
|
||||
private Namespace currentNamespace;
|
||||
private Namespace newNamespace;
|
||||
private SourceType source;
|
||||
|
||||
private String errorMsg = "";
|
||||
private String errorMessage = "";
|
||||
|
||||
/**
|
||||
* Constructs a new command for renaming a label within a specified namespace.
|
||||
* @param addr Address of label to be renamed.
|
||||
* @param oldName the current name of the label to be renamed.
|
||||
* @param newName the new name for the label. (null for default)
|
||||
* @param currentNamespace the symbol's current name space. (The namespace to associate this label with)
|
||||
* Constructs a new command for renaming <B>global</B> labels.
|
||||
*
|
||||
* @param addr Address of label to be renamed
|
||||
* @param oldName the name of the label to be renamed; may be null if the existing label is a
|
||||
* dynamic label
|
||||
* @param newName the new name for the label
|
||||
* @param source the source of this symbol
|
||||
*/
|
||||
public RenameLabelCmd(Address addr, String oldName, String newName, Namespace currentNamespace,
|
||||
public RenameLabelCmd(Address addr, String oldName, String newName, SourceType source) {
|
||||
this(addr, oldName, newName, null, null, source);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor renaming an existing symbol, but not changing its namespace
|
||||
*
|
||||
* @param symbol the existing symbol; may not be null
|
||||
* @param newName the new symbol name
|
||||
* @param source the desired symbol source
|
||||
*/
|
||||
public RenameLabelCmd(Symbol symbol, String newName, SourceType source) {
|
||||
this(symbol, newName, symbol.getParentNamespace(), source);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor renaming an existing symbol and changing its namespace. If you do not need
|
||||
* to change the namespace, then call {@link #RenameLabelCmd(Symbol, String, SourceType)}.
|
||||
*
|
||||
* @param symbol the existing symbol; may not be null
|
||||
* @param newName the new symbol name
|
||||
* @param newNamespace the new symbol namespace
|
||||
* @param source the desired symbol source
|
||||
*/
|
||||
public RenameLabelCmd(Symbol symbol, String newName, Namespace newNamespace,
|
||||
SourceType source) {
|
||||
this.addr = addr;
|
||||
this.oldName = oldName;
|
||||
|
||||
this.existingSymbol = Objects.requireNonNull(symbol);
|
||||
this.addr = symbol.getAddress();
|
||||
this.oldName = symbol.getName();
|
||||
this.newName = newName;
|
||||
this.currentNamespace = currentNamespace;
|
||||
this.newNamespace = currentNamespace;
|
||||
this.currentNamespace = symbol.getParentNamespace();
|
||||
this.newNamespace = newNamespace;
|
||||
this.source = source;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new command for renaming a label within currentNamespace and changing the
|
||||
* namespace to newNamespace.
|
||||
* @param addr Address of label to be renamed.
|
||||
* @param oldName the current name of the label to be renamed.
|
||||
*
|
||||
* @param addr Address of label to be renamed
|
||||
* @param oldName the current name of the label to be renamed
|
||||
* @param newName the new name for the label. (null for default)
|
||||
* @param currentNamespace the symbol's current parent name space (null indicates global namespace)
|
||||
* @param newNamespace final namespace (null indicates global namespace)
|
||||
* @param currentNamespace the symbol's current parent name space; null for global namespace
|
||||
* @param newNamespace the desired namespace; null for global namespace
|
||||
* @param source the source of this symbol
|
||||
*/
|
||||
public RenameLabelCmd(Address addr, String oldName, String newName, Namespace currentNamespace,
|
||||
private RenameLabelCmd(Address addr, String oldName, String newName, Namespace currentNamespace,
|
||||
Namespace newNamespace, SourceType source) {
|
||||
this(addr, oldName, newName, currentNamespace, source);
|
||||
this.addr = addr;
|
||||
this.oldName = oldName;
|
||||
this.newName = newName;
|
||||
this.currentNamespace = currentNamespace;
|
||||
this.newNamespace = newNamespace;
|
||||
this.source = source;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new command for renaming global labels.
|
||||
* @param addr Address of label to be renamed.
|
||||
* @param oldName the name of the label to be renamed; may be null
|
||||
* of the existing label is a dynamic label
|
||||
* @param newName the new name for the label
|
||||
* @param source the source of this symbol
|
||||
*/
|
||||
public RenameLabelCmd(Address addr, String oldName, String newName, SourceType source) {
|
||||
this(addr, oldName, newName, null, source);
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Rename Label";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getStatusMsg() {
|
||||
return errorMessage;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @see ghidra.framework.cmd.Command#applyTo(ghidra.framework.model.DomainObject)
|
||||
*/
|
||||
@Override
|
||||
public boolean applyTo(DomainObject obj) {
|
||||
|
||||
Program program = (Program) obj;
|
||||
if (currentNamespace == null) {
|
||||
currentNamespace = program.getGlobalNamespace();
|
||||
}
|
||||
|
||||
if (newNamespace == null) {
|
||||
newNamespace = program.getGlobalNamespace();
|
||||
}
|
||||
|
||||
SymbolTable st = ((Program) obj).getSymbolTable();
|
||||
Symbol s = null;
|
||||
if (oldName == null) {
|
||||
s = st.getPrimarySymbol(addr);
|
||||
}
|
||||
else {
|
||||
s = st.getSymbol(oldName, addr, currentNamespace);
|
||||
if (!parseNameAndNamespace(program, newNamespace, newName)) {
|
||||
return false; // errorMessage already set
|
||||
}
|
||||
|
||||
Symbol s = getSymbol(program);
|
||||
if (s == null) {
|
||||
errorMsg = "Symbol not found: " + oldName;
|
||||
return false; // errorMessage already set
|
||||
}
|
||||
|
||||
if (StringUtils.isBlank(newName) && s.getSource() != SourceType.DEFAULT) {
|
||||
errorMessage = "Cannot set non-default symbol name to \"\"";
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -120,45 +153,121 @@ public class RenameLabelCmd implements Command {
|
||||
}
|
||||
else {
|
||||
s.setName(newName, source);
|
||||
|
||||
if (newName.length() == 0 && s.getSource() != SourceType.DEFAULT) {
|
||||
errorMsg = "Rename failed - cannot set non-default symbol name to \"\"";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!newName.equals(s.getName())) {
|
||||
errorMsg = "Rename failed";
|
||||
errorMessage = "Rename failed";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
catch (DuplicateNameException e) {
|
||||
errorMsg = "Symbol already exists: " + newName;
|
||||
errorMessage = "Symbol already exists: " + newName;
|
||||
}
|
||||
catch (InvalidInputException e) {
|
||||
errorMsg = "Invalid entry: " + e.getMessage();
|
||||
errorMessage = "Invalid entry: " + e.getMessage();
|
||||
}
|
||||
catch (CircularDependencyException e) {
|
||||
errorMsg = e.getMessage();
|
||||
errorMessage = e.getMessage();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.framework.cmd.Command#getName()
|
||||
*/
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Rename Label";
|
||||
private boolean parseNameAndNamespace(Program program, Namespace rootNamespace, String name) {
|
||||
|
||||
SymbolPath symbolPath = getSymbolPath(name);
|
||||
if (symbolPath == null) {
|
||||
return false; // invalid symbol name
|
||||
}
|
||||
|
||||
// see if the user specified a namespace path
|
||||
Namespace parent = getOrCreateNamespaces(program, symbolPath, rootNamespace);
|
||||
if (parent == null) {
|
||||
return false; // create namespace failed
|
||||
}
|
||||
|
||||
// update the new namespace and symbol name to reflect the parse results
|
||||
newNamespace = parent;
|
||||
newName = symbolPath.getName();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.framework.cmd.Command#getStatusMsg()
|
||||
*/
|
||||
@Override
|
||||
public String getStatusMsg() {
|
||||
return errorMsg;
|
||||
private Symbol getSymbol(Program program) {
|
||||
|
||||
if (existingSymbol != null) {
|
||||
return existingSymbol;
|
||||
}
|
||||
|
||||
SymbolTable st = program.getSymbolTable();
|
||||
Symbol s = null;
|
||||
if (oldName != null) {
|
||||
s = st.getSymbol(oldName, addr, currentNamespace);
|
||||
}
|
||||
else {
|
||||
s = st.getPrimarySymbol(addr);
|
||||
if (s != null && !s.isDynamic()) {
|
||||
// noted by the constructor, a null name can only be used to rename dynamic symbols
|
||||
errorMessage = "Must specify name of symbol to be renamed";
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
if (s == null) {
|
||||
errorMessage = "Symbol not found: " + oldName;
|
||||
return null;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
// note: the root namespace will be used as the parent for any namespaces found in 'symbolPath'
|
||||
private Namespace getOrCreateNamespaces(Program program, SymbolPath symbolPath,
|
||||
Namespace rootNamespace) {
|
||||
SymbolPath parentPath = symbolPath.getParent();
|
||||
if (parentPath == null) {
|
||||
return rootNamespace;
|
||||
}
|
||||
|
||||
//
|
||||
// Prefer a non-function namespace. This allows us to put a function inside of a namespace
|
||||
// sharing the same name.
|
||||
//
|
||||
SymbolPath fullPath = new SymbolPath(rootNamespace.getSymbol()).append(parentPath);
|
||||
Namespace nonFunctionNs = NamespaceUtils.getNonFunctionNamespace(program, fullPath);
|
||||
if (nonFunctionNs != null) {
|
||||
return nonFunctionNs;
|
||||
}
|
||||
|
||||
//
|
||||
// At this point we can either reuse an existing function namespace or we have to create
|
||||
// a new non-function namespaces, depending upon the names being used. Only use an
|
||||
// existing function as a namespace if none of namespace path entries match the function
|
||||
// name.
|
||||
//
|
||||
String name = symbolPath.getName();
|
||||
if (!parentPath.containsPathEntry(name)) {
|
||||
Namespace functionNamespace =
|
||||
NamespaceUtils.getFunctionNamespaceContaining(program, parentPath, addr);
|
||||
if (functionNamespace != null) {
|
||||
return functionNamespace;
|
||||
}
|
||||
}
|
||||
|
||||
CreateNamespacesCmd cmd =
|
||||
new CreateNamespacesCmd(parentPath.getPath(), rootNamespace, SourceType.USER_DEFINED);
|
||||
if (cmd.applyTo(program)) {
|
||||
return cmd.getNamespace();
|
||||
}
|
||||
|
||||
errorMessage = cmd.getStatusMsg();
|
||||
return null;
|
||||
}
|
||||
|
||||
private SymbolPath getSymbolPath(String symbolName) {
|
||||
|
||||
if (StringUtils.isBlank(symbolName)) {
|
||||
errorMessage = "Name cannot be blank";
|
||||
return null;
|
||||
}
|
||||
|
||||
return new SymbolPath(symbolName);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -443,11 +443,7 @@ public class CodeBrowserClipboardProvider extends ByteCopier
|
||||
SymbolTable symbolTable = currentProgram.getSymbolTable();
|
||||
Symbol symbol = symbolTable.getSymbol(reference);
|
||||
if ((symbol instanceof CodeSymbol) || (symbol instanceof FunctionSymbol)) {
|
||||
String oldName = symbol.getName();
|
||||
Namespace namespace = symbol.getParentNamespace();
|
||||
Address symbolAddress = symbol.getAddress();
|
||||
RenameLabelCmd cmd = new RenameLabelCmd(symbolAddress, oldName, labelName, namespace,
|
||||
SourceType.USER_DEFINED);
|
||||
RenameLabelCmd cmd = new RenameLabelCmd(symbol, labelName, SourceType.USER_DEFINED);
|
||||
return tool.execute(cmd, currentProgram);
|
||||
}
|
||||
|
||||
|
||||
@@ -23,7 +23,6 @@ import ghidra.app.cmd.function.DeleteFunctionCmd;
|
||||
import ghidra.app.cmd.label.DeleteLabelCmd;
|
||||
import ghidra.app.cmd.label.RenameLabelCmd;
|
||||
import ghidra.docking.settings.Settings;
|
||||
import ghidra.framework.cmd.Command;
|
||||
import ghidra.framework.cmd.CompoundCmd;
|
||||
import ghidra.framework.plugintool.PluginTool;
|
||||
import ghidra.framework.plugintool.ServiceProvider;
|
||||
@@ -207,17 +206,19 @@ class SymbolTableModel extends AddressBasedTableModel<Symbol> {
|
||||
return;
|
||||
}
|
||||
|
||||
if (columnIndex == LABEL_COL) {
|
||||
String newName = aValue.toString();
|
||||
if (!symbol.getName().equals(newName)) {
|
||||
Command renameCmd = new RenameLabelCmd(symbol.getAddress(), symbol.getName(),
|
||||
newName, symbol.getParentNamespace(), SourceType.USER_DEFINED);
|
||||
if (columnIndex != LABEL_COL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!tool.execute(renameCmd, getProgram())) {
|
||||
Msg.showError(getClass(), provider.getComponent(), "Error Renaming Symbol",
|
||||
renameCmd.getStatusMsg());
|
||||
}
|
||||
}
|
||||
String newName = aValue.toString();
|
||||
if (symbol.getName().equals(newName)) {
|
||||
return;
|
||||
}
|
||||
|
||||
RenameLabelCmd renameCmd = new RenameLabelCmd(symbol, newName, SourceType.USER_DEFINED);
|
||||
if (!tool.execute(renameCmd, getProgram())) {
|
||||
Msg.showError(getClass(), provider.getComponent(), "Error Renaming Symbol",
|
||||
renameCmd.getStatusMsg());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -168,12 +168,16 @@ public class AddEditDialog extends DialogComponentProvider {
|
||||
cmd.add(new AddLabelCmd(addr, symbolName, parent, SourceType.USER_DEFINED));
|
||||
}
|
||||
else {
|
||||
cmd.add(new RenameLabelCmd(addr, symbol.getName(), symbolName,
|
||||
symbol.getParentNamespace(), parent, SourceType.USER_DEFINED));
|
||||
cmd.add(new RenameLabelCmd(symbol, labelText, namespace, SourceType.USER_DEFINED));
|
||||
isCurrentlyEntryPoint = symbol.isExternalEntryPoint();
|
||||
isCurrentlyPinned = symbol.isPinned();
|
||||
}
|
||||
|
||||
if (!tool.execute(cmd, program)) {
|
||||
setStatusText(cmd.getStatusMsg());
|
||||
return;
|
||||
}
|
||||
|
||||
if (primaryCheckBox.isEnabled() && primaryCheckBox.isSelected()) {
|
||||
cmd.add(new SetLabelPrimaryCmd(addr, symbolName, parent));
|
||||
}
|
||||
@@ -185,14 +189,12 @@ public class AddEditDialog extends DialogComponentProvider {
|
||||
cmd.add(new PinSymbolCmd(addr, symbolName, !isCurrentlyPinned));
|
||||
}
|
||||
|
||||
if (cmd.size() > 0) {
|
||||
|
||||
if (!tool.execute(cmd, program)) {
|
||||
setStatusText(cmd.getStatusMsg());
|
||||
return;
|
||||
}
|
||||
updateRecentLabels(symbolName);
|
||||
if (!tool.execute(cmd, program)) {
|
||||
setStatusText(cmd.getStatusMsg());
|
||||
return;
|
||||
}
|
||||
updateRecentLabels(symbolName);
|
||||
|
||||
program = null;
|
||||
close();
|
||||
}
|
||||
|
||||
@@ -430,8 +430,7 @@ public class ClearTest extends AbstractGhidraHeadedIntegrationTest {
|
||||
|
||||
Symbol[] symbols = program.getSymbolTable().getSymbols(addr("0x10022bf"));
|
||||
Symbol s = symbols[0];
|
||||
RenameLabelCmd cmd = new RenameLabelCmd(s.getAddress(), s.getName(), "Fred",
|
||||
s.getParentNamespace(), SourceType.USER_DEFINED);
|
||||
RenameLabelCmd cmd = new RenameLabelCmd(s, "Fred", SourceType.USER_DEFINED);
|
||||
applyCmd(program, cmd);
|
||||
|
||||
makeSelection(tool, program, addr("0x10022bf"), addr("0x10022c4"));
|
||||
|
||||
@@ -136,25 +136,25 @@ public class LabelActionTest extends AbstractGhidraHeadedIntegrationTest
|
||||
@Test
|
||||
public void testNotepadLocations() {
|
||||
ActionContext context = new ActionContext();
|
||||
assertEquals(false, addLabel.isEnabledForContext(context));
|
||||
assertFalse(addLabel.isEnabledForContext(context));
|
||||
|
||||
assertEquals(false, editLabel.isEnabledForContext(context));
|
||||
assertFalse(editLabel.isEnabledForContext(context));
|
||||
|
||||
assertEquals(false, removeLabel.isEnabledForContext(context));
|
||||
assertFalse(removeLabel.isEnabledForContext(context));
|
||||
|
||||
assertEquals(false, setLabel.isEnabledForContext(context));
|
||||
assertFalse(setLabel.isEnabledForContext(context));
|
||||
|
||||
env.open(program);
|
||||
cb.updateNow();
|
||||
|
||||
context = cb.getProvider().getActionContext(null);
|
||||
assertEquals(true, addLabel.isEnabledForContext(context));
|
||||
assertTrue(addLabel.isEnabledForContext(context));
|
||||
|
||||
assertEquals(false, editLabel.isEnabledForContext(context));
|
||||
assertFalse(editLabel.isEnabledForContext(context));
|
||||
|
||||
assertEquals(false, removeLabel.isEnabledForContext(context));
|
||||
assertFalse(removeLabel.isEnabledForContext(context));
|
||||
|
||||
assertEquals(false, setLabel.isEnabledForContext(context));
|
||||
assertFalse(setLabel.isEnabledForContext(context));
|
||||
|
||||
SampleLocationGenerator locGen = new SampleLocationGenerator(program);
|
||||
locGen.toggleOpenComposites(cb);
|
||||
@@ -162,9 +162,6 @@ public class LabelActionTest extends AbstractGhidraHeadedIntegrationTest
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.app.LocationCallback#locationGenerated(ghidra.program.singleuser.util.ProgramLocation)
|
||||
*/
|
||||
@Override
|
||||
public void locationGenerated(ProgramLocation loc) {
|
||||
|
||||
@@ -184,11 +181,11 @@ public class LabelActionTest extends AbstractGhidraHeadedIntegrationTest
|
||||
|
||||
if (loc instanceof LabelFieldLocation) {
|
||||
Symbol s = labelMgrPlugin.getSymbol((ListingActionContext) context);
|
||||
assertEquals(caseName, false, addLabel.isEnabledForContext(context));
|
||||
assertEquals(caseName, true, editLabel.isEnabledForContext(context));
|
||||
assertEquals(caseName, false, editExternalLocation.isEnabledForContext(context));
|
||||
assertFalse(caseName, addLabel.isEnabledForContext(context));
|
||||
assertTrue(caseName, editLabel.isEnabledForContext(context));
|
||||
assertFalse(caseName, editExternalLocation.isEnabledForContext(context));
|
||||
assertEquals(caseName, !s.isDynamic(), removeLabel.isEnabledForContext(context));
|
||||
assertEquals(caseName, false, setLabel.isEnabledForContext(context));
|
||||
assertFalse(caseName, setLabel.isEnabledForContext(context));
|
||||
|
||||
assertEquals(EditLabelAction.EDIT_LABEL,
|
||||
editLabel.getPopupMenuData().getMenuItemName());
|
||||
@@ -249,8 +246,8 @@ public class LabelActionTest extends AbstractGhidraHeadedIntegrationTest
|
||||
|
||||
assertEquals(caseName, !hasComponentPath, addLabel.isEnabledForContext(context));
|
||||
assertEquals(caseName, component != null, editLabel.isEnabledForContext(context));
|
||||
assertEquals(caseName, false, removeLabel.isEnabledForContext(context));
|
||||
assertEquals(caseName, false, setLabel.isEnabledForContext(context));
|
||||
assertFalse(caseName, removeLabel.isEnabledForContext(context));
|
||||
assertFalse(caseName, setLabel.isEnabledForContext(context));
|
||||
|
||||
if (component != null) {
|
||||
assertEquals(EditLabelAction.EDIT_FIELDNAME,
|
||||
@@ -258,16 +255,16 @@ public class LabelActionTest extends AbstractGhidraHeadedIntegrationTest
|
||||
}
|
||||
}
|
||||
else if (!(loc instanceof FunctionLocation)) {
|
||||
assertEquals(caseName, true, addLabel.isEnabledForContext(context));
|
||||
assertEquals(caseName, false, editLabel.isEnabledForContext(context));
|
||||
assertEquals(caseName, false, removeLabel.isEnabledForContext(context));
|
||||
assertEquals(caseName, false, setLabel.isEnabledForContext(context));
|
||||
assertTrue(caseName, addLabel.isEnabledForContext(context));
|
||||
assertFalse(caseName, editLabel.isEnabledForContext(context));
|
||||
assertFalse(caseName, removeLabel.isEnabledForContext(context));
|
||||
assertFalse(caseName, setLabel.isEnabledForContext(context));
|
||||
}
|
||||
else {
|
||||
assertEquals(caseName, false, addLabel.isEnabledForContext(context));
|
||||
assertEquals(caseName, false, editLabel.isEnabledForContext(context));
|
||||
assertEquals(caseName, false, removeLabel.isEnabledForContext(context));
|
||||
assertEquals(caseName, false, setLabel.isEnabledForContext(context));
|
||||
assertFalse(caseName, addLabel.isEnabledForContext(context));
|
||||
assertFalse(caseName, editLabel.isEnabledForContext(context));
|
||||
assertFalse(caseName, removeLabel.isEnabledForContext(context));
|
||||
assertFalse(caseName, setLabel.isEnabledForContext(context));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,6 @@ import javax.swing.JTextField;
|
||||
import org.junit.*;
|
||||
|
||||
import ghidra.app.cmd.function.CreateFunctionCmd;
|
||||
import ghidra.app.events.ProgramSelectionPluginEvent;
|
||||
import ghidra.app.plugin.core.codebrowser.CodeBrowserPlugin;
|
||||
import ghidra.app.services.ProgramManager;
|
||||
import ghidra.framework.Application;
|
||||
@@ -33,7 +32,6 @@ import ghidra.framework.plugintool.PluginTool;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.listing.Program;
|
||||
import ghidra.program.model.symbol.*;
|
||||
import ghidra.program.util.ProgramSelection;
|
||||
import ghidra.test.*;
|
||||
|
||||
/**
|
||||
@@ -58,8 +56,9 @@ public class AutoRenameLabelsScriptTest extends AbstractGhidraHeadedIntegrationT
|
||||
|
||||
env.showTool();
|
||||
script =
|
||||
Application.getModuleFile("Base", "ghidra_scripts/AutoRenameLabelsScript.java").getFile(
|
||||
true);
|
||||
Application.getModuleFile("Base", "ghidra_scripts/AutoRenameLabelsScript.java")
|
||||
.getFile(
|
||||
true);
|
||||
|
||||
env.showTool();
|
||||
}
|
||||
@@ -88,12 +87,8 @@ public class AutoRenameLabelsScriptTest extends AbstractGhidraHeadedIntegrationT
|
||||
return builder.getProgram();
|
||||
}
|
||||
|
||||
/*
|
||||
* @see TestCase#tearDown()
|
||||
*/
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
env.release(program);
|
||||
env.dispose();
|
||||
}
|
||||
|
||||
@@ -102,29 +97,23 @@ public class AutoRenameLabelsScriptTest extends AbstractGhidraHeadedIntegrationT
|
||||
SymbolTable symbolTable = program.getSymbolTable();
|
||||
Symbol s1 = symbolTable.getPrimarySymbol(addr(0x01003a94));
|
||||
assertNotNull(s1);
|
||||
assertTrue(s1.getSource() == SourceType.DEFAULT);
|
||||
assertEquals(s1.getSource(), SourceType.DEFAULT);
|
||||
|
||||
Symbol s2 = symbolTable.getPrimarySymbol(addr(0x01003a97));
|
||||
assertNotNull(s2);
|
||||
assertTrue(s2.getSource() == SourceType.DEFAULT);
|
||||
assertEquals(s2.getSource(), SourceType.DEFAULT);
|
||||
|
||||
ProgramSelection sel = new ProgramSelection(addr(0x01003a94), addr(0x01003a9b));
|
||||
tool.firePluginEvent(new ProgramSelectionPluginEvent("test", sel, program));
|
||||
waitForPostedSwingRunnables();
|
||||
makeSelection(tool, program, addr(0x01003a94), addr(0x01003a9b));
|
||||
|
||||
ScriptTaskListener scriptID = env.runScript(script);
|
||||
|
||||
JDialog dialog = waitForJDialog(tool.getToolFrame(), "Auto Rename Labels", 2000);
|
||||
final JTextField tf = findComponent(dialog, JTextField.class);
|
||||
JDialog dialog = waitForJDialog("Auto Rename Labels");
|
||||
JTextField tf = findComponent(dialog, JTextField.class);
|
||||
runSwing(() -> tf.setText("My_Label"));
|
||||
pressButtonByText(dialog, "OK");
|
||||
waitForScriptCompletion(scriptID, 100000);
|
||||
|
||||
program.flushEvents();
|
||||
waitForPostedSwingRunnables();
|
||||
|
||||
s1 = symbolTable.getPrimarySymbol(addr(0x01003a94));
|
||||
s2 = symbolTable.getPrimarySymbol(addr(0x01003a97));
|
||||
waitForProgram(program);
|
||||
|
||||
assertEquals("My_Label1", s1.getName());
|
||||
assertEquals("My_Label2", s2.getName());
|
||||
@@ -134,39 +123,34 @@ public class AutoRenameLabelsScriptTest extends AbstractGhidraHeadedIntegrationT
|
||||
public void testNoRenameOnUserDefined() throws Exception {
|
||||
SymbolTable symbolTable = program.getSymbolTable();
|
||||
Symbol s1 = symbolTable.getPrimarySymbol(addr(0x010046cc));
|
||||
assertTrue(s1.getSource() == SourceType.DEFAULT);
|
||||
assertEquals(s1.getSource(), SourceType.DEFAULT);
|
||||
|
||||
// create a function at 10046d0 so we don't have a default label
|
||||
CreateFunctionCmd cmd =
|
||||
new CreateFunctionCmd("My_Function1", addr(0x010046d0), null, SourceType.ANALYSIS);
|
||||
tool.execute(cmd, program);
|
||||
program.flushEvents();
|
||||
waitForPostedSwingRunnables();
|
||||
applyCmd(program, cmd);
|
||||
|
||||
Symbol s2 = symbolTable.getPrimarySymbol(addr(0x010046d0));
|
||||
assertNotNull(s2);
|
||||
assertTrue(s2.getSource() != SourceType.DEFAULT);
|
||||
assertNotEquals(s2.getSource(), SourceType.DEFAULT);
|
||||
String s2Name = s2.getName();
|
||||
|
||||
ProgramSelection sel = new ProgramSelection(addr(0x010046cc), addr(0x010046d0));
|
||||
tool.firePluginEvent(new ProgramSelectionPluginEvent("test", sel, program));
|
||||
waitForPostedSwingRunnables();
|
||||
makeSelection(tool, program, addr(0x010046cc), addr(0x010046d0));
|
||||
|
||||
ScriptTaskListener scriptID = env.runScript(script);
|
||||
|
||||
JDialog dialog = waitForJDialog(tool.getToolFrame(), "Auto Rename Labels", 2000);
|
||||
final JTextField tf = findComponent(dialog, JTextField.class);
|
||||
JDialog dialog = waitForJDialog("Auto Rename Labels");
|
||||
JTextField tf = findComponent(dialog, JTextField.class);
|
||||
runSwing(() -> tf.setText("My_Label"));
|
||||
pressButtonByText(dialog, "OK");
|
||||
waitForScriptCompletion(scriptID, 100000);
|
||||
|
||||
program.flushEvents();
|
||||
waitForPostedSwingRunnables();
|
||||
s1 = symbolTable.getPrimarySymbol(addr(0x010046cc));
|
||||
waitForProgram(program);
|
||||
|
||||
assertEquals("My_Label1", s1.getName());
|
||||
|
||||
// only dynamic label should get renamed
|
||||
s2 = symbolTable.getPrimarySymbol(addr(0x010046d0));
|
||||
assertTrue(!s2.getName().equals("My_Label2"));
|
||||
assertFalse(s2.getName().equals("My_Label2"));
|
||||
assertEquals(s2Name, s2.getName());
|
||||
}
|
||||
|
||||
|
||||
@@ -450,21 +450,16 @@ public class SymbolTreeNavigationTest extends AbstractProgramBasedTest {
|
||||
}
|
||||
|
||||
private void rename(Symbol symbol, String newName) {
|
||||
|
||||
String oldName = symbol.getName();
|
||||
RenameLabelCmd cmd =
|
||||
new RenameLabelCmd(symbol.getAddress(), oldName, newName, SourceType.USER_DEFINED);
|
||||
RenameLabelCmd cmd = new RenameLabelCmd(symbol, newName, SourceType.USER_DEFINED);
|
||||
applyCmd(cmd);
|
||||
util.waitForTree();
|
||||
}
|
||||
|
||||
private Symbol createGlobalLabel(Address addr) {
|
||||
|
||||
return createGlobalLabel(addr, "GlobalLabel");
|
||||
}
|
||||
|
||||
private Symbol createGlobalLabel(Address addr, String labelName) {
|
||||
|
||||
AddLabelCmd cmd = new AddLabelCmd(addr, labelName, SourceType.USER_DEFINED);
|
||||
applyCmd(cmd);
|
||||
Symbol symbol = cmd.getSymbol();
|
||||
|
||||
@@ -28,6 +28,7 @@ import java.util.function.BiConsumer;
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.ChangeEvent;
|
||||
import javax.swing.table.TableModel;
|
||||
import javax.swing.text.JTextComponent;
|
||||
|
||||
import org.jdom.Element;
|
||||
import org.junit.*;
|
||||
@@ -346,12 +347,47 @@ public class SymbolTablePluginTest extends AbstractGhidraHeadedIntegrationTest {
|
||||
|
||||
waitForNotBusy();
|
||||
|
||||
assertTrue(!symbolTable.isEditing());
|
||||
assertFalse(symbolTable.isEditing());
|
||||
|
||||
Symbol s = getSymbol(row);
|
||||
assertEquals("ghidra.Is.Cool", s.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEditName_AddNamespace() throws Exception {
|
||||
openProgram("sample");
|
||||
|
||||
waitForNotBusy();
|
||||
|
||||
String symbolName = "ghidra";
|
||||
int row = findRow(symbolName);
|
||||
|
||||
doubleClick(symbolTable, row, SymbolTableModel.LABEL_COL);
|
||||
waitForSwing();
|
||||
assertTrue(symbolTable.isEditing());
|
||||
|
||||
Component editor = symbolTable.getEditorComponent();
|
||||
assertNotNull(editor);
|
||||
JTextField textField = (JTextField) editor;
|
||||
String currentText = getText(textField);
|
||||
assertEquals(symbolName, currentText);
|
||||
|
||||
String newNamespaceName = "NS1";
|
||||
JTextComponent textComponent = (JTextComponent) editor;
|
||||
runSwing(() -> textComponent.selectAll());
|
||||
myTypeText(editor, newNamespaceName + Namespace.DELIMITER + symbolName);
|
||||
runSwing(() -> symbolTable.editingStopped(new ChangeEvent(symbolTable)));
|
||||
|
||||
waitForNotBusy();
|
||||
|
||||
assertFalse(symbolTable.isEditing());
|
||||
|
||||
Symbol s = getSymbol(row);
|
||||
assertEquals(symbolName, s.getName());
|
||||
Namespace namespace = s.getParentNamespace();
|
||||
assertEquals(newNamespaceName, namespace.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testQuickLookup() throws Exception {
|
||||
openProgram("sample");
|
||||
@@ -400,7 +436,7 @@ public class SymbolTablePluginTest extends AbstractGhidraHeadedIntegrationTest {
|
||||
openProgram("sample");
|
||||
|
||||
int rowCount = symbolTable.getRowCount();
|
||||
assertTrue(!deleteAction.isEnabled());
|
||||
assertFalse(deleteAction.isEnabled());
|
||||
|
||||
int row = findRow("ghidra");
|
||||
Rectangle rect = symbolTable.getCellRect(row, 0, true);
|
||||
@@ -488,7 +524,7 @@ public class SymbolTablePluginTest extends AbstractGhidraHeadedIntegrationTest {
|
||||
public void testMakeSelection() throws Exception {
|
||||
openProgram("sample");
|
||||
|
||||
assertTrue(!makeSelectionAction.isEnabled());
|
||||
assertFalse(makeSelectionAction.isEnabled());
|
||||
|
||||
int row1 = findRow("ghidra");
|
||||
int row2 = findRow("KERNEL32.dll_GetProcAddress");
|
||||
|
||||
@@ -508,8 +508,10 @@ public class FillOutStructureCmd extends BackgroundCommand {
|
||||
if (isThisParam) {
|
||||
Namespace rootNamespace = currentProgram.getGlobalNamespace();
|
||||
Namespace newNamespace = createUniqueClassName(rootNamespace);
|
||||
RenameLabelCmd command = new RenameLabelCmd(f.getEntryPoint(), f.getName(), f.getName(),
|
||||
rootNamespace, newNamespace, SourceType.USER_DEFINED);
|
||||
String name = f.getName();
|
||||
Symbol symbol = f.getSymbol();
|
||||
RenameLabelCmd command =
|
||||
new RenameLabelCmd(symbol, name, newNamespace, SourceType.USER_DEFINED);
|
||||
if (!command.applyTo(currentProgram)) {
|
||||
return null;
|
||||
}
|
||||
@@ -545,12 +547,10 @@ public class FillOutStructureCmd extends BackgroundCommand {
|
||||
symbolTable.createClass(rootNamespace, newClassName, SourceType.USER_DEFINED);
|
||||
}
|
||||
catch (DuplicateNameException e) {
|
||||
// Shouldn't happen
|
||||
e.printStackTrace();
|
||||
Msg.error(this, "Error creating class '" + newClassName + "'", e);
|
||||
}
|
||||
catch (InvalidInputException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
Msg.error(this, "Error creating class '" + newClassName + "'", e);
|
||||
}
|
||||
return newClass;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user