diff --git a/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/service/tracermi/TraceRmiHandler.java b/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/service/tracermi/TraceRmiHandler.java index 19c73acd5c..b1e6847435 100644 --- a/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/service/tracermi/TraceRmiHandler.java +++ b/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/service/tracermi/TraceRmiHandler.java @@ -322,8 +322,7 @@ public class TraceRmiHandler implements TraceRmiConnection { } } - protected DomainFolder getOrCreateNewTracesFolder() - throws InvalidNameException, IOException { + protected DomainFolder getOrCreateNewTracesFolder() throws InvalidNameException, IOException { return getOrCreateFolder(plugin.getTool().getProject().getProjectData().getRootFolder(), "New Traces"); } @@ -494,10 +493,8 @@ public class TraceRmiHandler implements TraceRmiConnection { return rep == null ? null : rep.build(); } catch (Throwable e) { - return rep - .setError(ReplyError.newBuilder() - .setMessage( - e.getMessage() + "\n" + ExceptionUtils.getStackTrace(e))) + return rep.setError(ReplyError.newBuilder() + .setMessage(e.getMessage() + "\n" + ExceptionUtils.getStackTrace(e))) .build(); } } @@ -509,8 +506,8 @@ public class TraceRmiHandler implements TraceRmiConnection { req.getRequestActivate().getOid().getId(), req.getRequestActivate().getObject().getId(), req.getRequestActivate().getObject().getPath().getPath()); - case REQUEST_END_TX -> "endTx(%d)".formatted( - req.getRequestEndTx().getTxid().getId()); + case REQUEST_END_TX -> "endTx(%d)" + .formatted(req.getRequestEndTx().getTxid().getId()); case REQUEST_START_TX -> "startTx(%d,%s)".formatted( req.getRequestStartTx().getTxid().getId(), req.getRequestStartTx().getDescription()); @@ -530,49 +527,40 @@ public class TraceRmiHandler implements TraceRmiConnection { } final Dispatcher dispatchNegotiate = (req, rep) -> switch (req.getMsgCase()) { - case REQUEST_NEGOTIATE -> rep - .setReplyNegotiate(handleNegotiate(req.getRequestNegotiate())); + case REQUEST_NEGOTIATE -> rep.setReplyNegotiate(handleNegotiate(req.getRequestNegotiate())); default -> throw new InvalidRequestError(req); }; final Dispatcher dispatchNominal = (req, rep) -> switch (req.getMsgCase()) { - case REQUEST_ACTIVATE -> rep - .setReplyActivate(handleActivate(req.getRequestActivate())); + case REQUEST_ACTIVATE -> rep.setReplyActivate(handleActivate(req.getRequestActivate())); case REQUEST_CLOSE_TRACE -> rep .setReplyCloseTrace(handleCloseTrace(req.getRequestCloseTrace())); case REQUEST_CREATE_OBJECT -> rep .setReplyCreateObject(handleCreateObject(req.getRequestCreateObject())); case REQUEST_CREATE_OVERLAY -> rep - .setReplyCreateOverlay( - handleCreateOverlay(req.getRequestCreateOverlay())); + .setReplyCreateOverlay(handleCreateOverlay(req.getRequestCreateOverlay())); case REQUEST_CREATE_ROOT_OBJECT -> rep - .setReplyCreateObject( - handleCreateRootObject(req.getRequestCreateRootObject())); + .setReplyCreateObject(handleCreateRootObject(req.getRequestCreateRootObject())); case REQUEST_CREATE_TRACE -> rep .setReplyCreateTrace(handleCreateTrace(req.getRequestCreateTrace())); case REQUEST_DELETE_BYTES -> rep .setReplyDeleteBytes(handleDeleteBytes(req.getRequestDeleteBytes())); - case REQUEST_DELETE_REGISTER_VALUE -> rep - .setReplyDeleteRegisterValue( - handleDeleteRegisterValue(req.getRequestDeleteRegisterValue())); + case REQUEST_DELETE_REGISTER_VALUE -> rep.setReplyDeleteRegisterValue( + handleDeleteRegisterValue(req.getRequestDeleteRegisterValue())); case REQUEST_DISASSEMBLE -> rep .setReplyDisassemble(handleDisassemble(req.getRequestDisassemble())); - case REQUEST_END_TX -> rep - .setReplyEndTx(handleEndTx(req.getRequestEndTx())); + case REQUEST_END_TX -> rep.setReplyEndTx(handleEndTx(req.getRequestEndTx())); case REQUEST_GET_OBJECT -> rep .setReplyGetObject(handleGetObject(req.getRequestGetObject())); case REQUEST_GET_VALUES -> rep .setReplyGetValues(handleGetValues(req.getRequestGetValues())); - case REQUEST_GET_VALUES_INTERSECTING -> rep - .setReplyGetValues( - handleGetValuesIntersecting(req.getRequestGetValuesIntersecting())); + case REQUEST_GET_VALUES_INTERSECTING -> rep.setReplyGetValues( + handleGetValuesIntersecting(req.getRequestGetValuesIntersecting())); case REQUEST_INSERT_OBJECT -> rep .setReplyInsertObject(handleInsertObject(req.getRequestInsertObject())); - case REQUEST_PUT_BYTES -> rep - .setReplyPutBytes(handlePutBytes(req.getRequestPutBytes())); + case REQUEST_PUT_BYTES -> rep.setReplyPutBytes(handlePutBytes(req.getRequestPutBytes())); case REQUEST_PUT_REGISTER_VALUE -> rep - .setReplyPutRegisterValue( - handlePutRegisterValue(req.getRequestPutRegisterValue())); + .setReplyPutRegisterValue(handlePutRegisterValue(req.getRequestPutRegisterValue())); case REQUEST_REMOVE_OBJECT -> rep .setReplyRemoveObject(handleRemoveObject(req.getRequestRemoveObject())); case REQUEST_RETAIN_VALUES -> rep @@ -580,14 +568,10 @@ public class TraceRmiHandler implements TraceRmiConnection { case REQUEST_SAVE_TRACE -> rep .setReplySaveTrace(handleSaveTrace(req.getRequestSaveTrace())); case REQUEST_SET_MEMORY_STATE -> rep - .setReplySetMemoryState( - handleSetMemoryState(req.getRequestSetMemoryState())); - case REQUEST_SET_VALUE -> rep - .setReplySetValue(handleSetValue(req.getRequestSetValue())); - case REQUEST_SNAPSHOT -> rep - .setReplySnapshot(handleSnapshot(req.getRequestSnapshot())); - case REQUEST_START_TX -> rep - .setReplyStartTx(handleStartTx(req.getRequestStartTx())); + .setReplySetMemoryState(handleSetMemoryState(req.getRequestSetMemoryState())); + case REQUEST_SET_VALUE -> rep.setReplySetValue(handleSetValue(req.getRequestSetValue())); + case REQUEST_SNAPSHOT -> rep.setReplySnapshot(handleSnapshot(req.getRequestSnapshot())); + case REQUEST_START_TX -> rep.setReplyStartTx(handleStartTx(req.getRequestStartTx())); case XREPLY_INVOKE_METHOD -> handleXInvokeMethod(req.getXreplyInvokeMethod()); default -> throw new InvalidRequestError(req); }; @@ -666,15 +650,11 @@ public class TraceRmiHandler implements TraceRmiConnection { } protected static ObjSpec makeObjSpec(TraceObject object) { - return ObjSpec.newBuilder() - .setId(object.getKey()) - .build(); + return ObjSpec.newBuilder().setId(object.getKey()).build(); } protected static ObjPath makeObjPath(TraceObjectKeyPath path) { - return ObjPath.newBuilder() - .setPath(path.toString()) - .build(); + return ObjPath.newBuilder().setPath(path.toString()).build(); } protected static ObjDesc makeObjDesc(TraceObject object) { @@ -767,15 +747,13 @@ public class TraceRmiHandler implements TraceRmiConnection { if (value instanceof int[] ia) { return Value.newBuilder() .setIntArrValue( - IntArr.newBuilder() - .addAllArr(IntStream.of(ia).mapToObj(i -> i).toList())) + IntArr.newBuilder().addAllArr(IntStream.of(ia).mapToObj(i -> i).toList())) .build(); } if (value instanceof long[] la) { return Value.newBuilder() .setLongArrValue( - LongArr.newBuilder() - .addAllArr(LongStream.of(la).mapToObj(l -> l).toList())) + LongArr.newBuilder().addAllArr(LongStream.of(la).mapToObj(l -> l).toList())) .build(); } if (value instanceof String[] sa) { @@ -847,8 +825,7 @@ public class TraceRmiHandler implements TraceRmiConnection { protected ReplyCreateObject handleCreateObject(RequestCreateObject req) { OpenTrace open = requireOpenTrace(req.getOid()); - TraceObject object = - open.trace.getObjectManager().createObject(toKeyPath(req.getPath())); + TraceObject object = open.trace.getObjectManager().createObject(toKeyPath(req.getPath())); return ReplyCreateObject.newBuilder().setObject(makeObjSpec(object)).build(); } @@ -904,8 +881,7 @@ public class TraceRmiHandler implements TraceRmiConnection { return ReplyDeleteBytes.getDefaultInstance(); } - protected ReplyDeleteRegisterValue handleDeleteRegisterValue( - RequestDeleteRegisterValue req) { + protected ReplyDeleteRegisterValue handleDeleteRegisterValue(RequestDeleteRegisterValue req) { OpenTrace open = requireOpenTrace(req.getOid()); long snap = req.getSnap().getSnap(); AddressSpace space = open.trace.getBaseAddressFactory().getAddressSpace(req.getSpace()); @@ -932,15 +908,13 @@ public class TraceRmiHandler implements TraceRmiConnection { // Want addresses satisfying {@code known | (readOnly & everKnown)} TraceMemoryManager memoryManager = open.trace.getMemoryManager(); - AddressSetView readOnly = - memoryManager.getRegionsAddressSetWith(snap, r -> !r.isWrite()); + AddressSetView readOnly = memoryManager.getRegionsAddressSetWith(snap, r -> !r.isWrite()); AddressSetView everKnown = memoryManager.getAddressesWithState(Lifespan.since(snap), s -> s == TraceMemoryState.KNOWN); AddressSetView roEverKnown = new IntersectionAddressSetView(readOnly, everKnown); AddressSetView known = memoryManager.getAddressesWithState(snap, s -> s == TraceMemoryState.KNOWN); - AddressSetView disassemblable = - new AddressSet(new UnionAddressSetView(known, roEverKnown)); + AddressSetView disassemblable = new AddressSet(new UnionAddressSetView(known, roEverKnown)); Address start = open.toAddress(req.getStart(), true); TracePlatform host = open.trace.getPlatformManager().getHostPlatform(); @@ -950,7 +924,7 @@ public class TraceRmiHandler implements TraceRmiConnection { host.getLanguage(), host.getLanguage().getLanguageID(), start)); try (CloseableTaskMonitor monitor = plugin.createMonitor()) { - dis.applyToTyped(open.trace.getFixedProgramView(snap), monitor); + dis.applyTo(open.trace.getFixedProgramView(snap), monitor); } return ReplyDisassemble.newBuilder() @@ -988,21 +962,19 @@ public class TraceRmiHandler implements TraceRmiConnection { OpenTrace open = requireOpenTrace(req.getOid()); return ReplyGetValues.newBuilder() .addAllValues(open.trace.getObjectManager() - .getValuePaths(toLifespan(req.getSpan()), - toPathPattern(req.getPattern())) + .getValuePaths(toLifespan(req.getSpan()), toPathPattern(req.getPattern())) .map(TraceRmiHandler::makeValDesc) .sorted(Comparator.comparing(ValDesc::getKey)) .toList()) .build(); } - protected ReplyGetValues handleGetValuesIntersecting( - RequestGetValuesIntersecting req) throws AddressOverflowException { + protected ReplyGetValues handleGetValuesIntersecting(RequestGetValuesIntersecting req) + throws AddressOverflowException { OpenTrace open = requireOpenTrace(req.getOid()); AddressRange range = open.toRange(req.getBox().getRange(), false); String key = req.getKey() == "" ? null : req.getKey(); - Collection col = range == null - ? List.of() + Collection col = range == null ? List.of() : open.trace.getObjectManager() .getValuesIntersecting(toLifespan(req.getBox().getSpan()), range, key); return ReplyGetValues.newBuilder() @@ -1018,9 +990,7 @@ public class TraceRmiHandler implements TraceRmiConnection { .stream() .map(TraceObjectValue::getLifespan) .reduce(Lifespan.ALL, Lifespan::intersect); - return ReplyInsertObject.newBuilder() - .setSpan(makeSpan(span)) - .build(); + return ReplyInsertObject.newBuilder().setSpan(makeSpan(span)).build(); } protected ReplyNegotiate handleNegotiate(RequestNegotiate req) { @@ -1031,8 +1001,8 @@ public class TraceRmiHandler implements TraceRmiConnection { } for (Method m : req.getMethodsList()) { RemoteMethod rm = new RecordRemoteMethod(this, m.getName(), - ActionName.name(m.getAction()), m.getDisplay(), - m.getDescription(), m.getParametersList() + ActionName.name(m.getAction()), m.getDisplay(), m.getDescription(), + m.getParametersList() .stream() .collect(Collectors.toMap(MethodParameter::getName, this::makeParameter)), new SchemaName(m.getReturnType().getName())); @@ -1141,8 +1111,7 @@ public class TraceRmiHandler implements TraceRmiConnection { return ReplySetMemoryState.getDefaultInstance(); } - protected ReplySetValue handleSetValue(RequestSetValue req) - throws AddressOverflowException { + protected ReplySetValue handleSetValue(RequestSetValue req) throws AddressOverflowException { ValSpec value = req.getValue(); OpenTrace open = requireOpenTrace(req.getOid()); Object objVal = open.toValue(value.getValue()); @@ -1152,8 +1121,8 @@ public class TraceRmiHandler implements TraceRmiConnection { return ReplySetValue.newBuilder().setSpan(makeSpan(Lifespan.EMPTY)).build(); } - TraceObjectValue val = object.setValue(toLifespan(value.getSpan()), value.getKey(), - objVal, toResolution(req.getResolution())); + TraceObjectValue val = object.setValue(toLifespan(value.getSpan()), value.getKey(), objVal, + toResolution(req.getResolution())); return ReplySetValue.newBuilder() .setSpan(makeSpan(val == null ? Lifespan.EMPTY : val.getLifespan())) .build(); diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/disassemble/CurrentPlatformTraceDisassembleCommand.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/disassemble/CurrentPlatformTraceDisassembleCommand.java index ea4d1d47c5..5a0de9f427 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/disassemble/CurrentPlatformTraceDisassembleCommand.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/disassemble/CurrentPlatformTraceDisassembleCommand.java @@ -22,7 +22,7 @@ import ghidra.app.services.DebuggerTraceManagerService; import ghidra.debug.api.platform.DebuggerPlatformMapper; import ghidra.debug.api.platform.DisassemblyResult; import ghidra.debug.api.tracemgr.DebuggerCoordinates; -import ghidra.framework.cmd.TypedBackgroundCommand; +import ghidra.framework.cmd.BackgroundCommand; import ghidra.framework.plugintool.PluginTool; import ghidra.program.model.address.Address; import ghidra.program.model.address.AddressSetView; @@ -33,7 +33,7 @@ import ghidra.trace.model.thread.TraceThread; import ghidra.util.task.TaskMonitor; public final class CurrentPlatformTraceDisassembleCommand - extends TypedBackgroundCommand { + extends BackgroundCommand { public static final String NAME = "Disassemble"; public record Reqs(DebuggerPlatformMapper mapper, TraceThread thread, TraceObject object, @@ -48,8 +48,7 @@ public final class CurrentPlatformTraceDisassembleCommand return null; } Trace trace = view.getTrace(); - DebuggerCoordinates current = traceManager == null - ? DebuggerCoordinates.NOWHERE + DebuggerCoordinates current = traceManager == null ? DebuggerCoordinates.NOWHERE : traceManager.getCurrentFor(trace); TraceThread thread = current.getThread(); TraceObject object = current.getObject(); @@ -74,8 +73,8 @@ public final class CurrentPlatformTraceDisassembleCommand private final Reqs reqs; private final Address address; - public CurrentPlatformTraceDisassembleCommand(PluginTool tool, AddressSetView set, - Reqs reqs, Address address) { + public CurrentPlatformTraceDisassembleCommand(PluginTool tool, AddressSetView set, Reqs reqs, + Address address) { super(NAME, true, true, false); this.tool = tool; this.set = set; @@ -84,9 +83,9 @@ public final class CurrentPlatformTraceDisassembleCommand } @Override - public boolean applyToTyped(TraceProgramView view, TaskMonitor monitor) { - DisassemblyResult result = reqs.mapper.disassemble( - reqs.thread, reqs.object, address, set, view.getSnap(), monitor); + public boolean applyTo(TraceProgramView view, TaskMonitor monitor) { + DisassemblyResult result = reqs.mapper.disassemble(reqs.thread, reqs.object, address, set, + view.getSnap(), monitor); if (!result.isSuccess()) { tool.setStatusInfo(result.getErrorMessage(), true); } diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/disassemble/TraceDisassembleCommand.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/disassemble/TraceDisassembleCommand.java index 3122fa331b..94c77f1c8a 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/disassemble/TraceDisassembleCommand.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/disassemble/TraceDisassembleCommand.java @@ -15,7 +15,7 @@ */ package ghidra.app.plugin.core.debug.disassemble; -import ghidra.framework.cmd.TypedBackgroundCommand; +import ghidra.framework.cmd.BackgroundCommand; import ghidra.program.disassemble.Disassembler; import ghidra.program.model.address.*; import ghidra.program.model.lang.*; @@ -27,7 +27,7 @@ import ghidra.trace.model.program.TraceProgramView; import ghidra.util.MathUtilities; import ghidra.util.task.TaskMonitor; -public class TraceDisassembleCommand extends TypedBackgroundCommand { +public class TraceDisassembleCommand extends BackgroundCommand { protected final TracePlatform platform; protected final Address start; @@ -76,7 +76,7 @@ public class TraceDisassembleCommand extends TypedBackgroundCommand(obj, RecorderPermanentTransaction::start, delayMs); this.threads = new ExecutorService[threadCount]; for (int i = 0; i < threadCount; i++) { - ThreadFactory factory = new BasicThreadFactory.Builder() - .namingPattern(name + "thread-" + i + "-%d") - .build(); + ThreadFactory factory = + new BasicThreadFactory.Builder().namingPattern(name + "thread-" + i + "-%d") + .build(); threads[i] = Executors.newSingleThreadExecutor(factory); } } diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/RecorderPermanentTransaction.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/RecorderPermanentTransaction.java index 6dcc822b9c..fefa9c6abd 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/RecorderPermanentTransaction.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/model/RecorderPermanentTransaction.java @@ -16,19 +16,19 @@ package ghidra.app.plugin.core.debug.service.model; import db.Transaction; -import ghidra.framework.model.UndoableDomainObject; +import ghidra.framework.model.DomainObject; public class RecorderPermanentTransaction implements AutoCloseable { - public static RecorderPermanentTransaction start(UndoableDomainObject obj, String description) { + public static RecorderPermanentTransaction start(DomainObject obj, String description) { Transaction tx = obj.openTransaction(description); return new RecorderPermanentTransaction(obj, tx); } - private final UndoableDomainObject obj; + private final DomainObject obj; private final Transaction tx; - public RecorderPermanentTransaction(UndoableDomainObject obj, Transaction tx) { + public RecorderPermanentTransaction(DomainObject obj, Transaction tx) { this.obj = obj; this.tx = tx; } diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/modules/MapModulesBackgroundCommand.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/modules/MapModulesBackgroundCommand.java index ded0013c33..3a9f2e9e07 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/modules/MapModulesBackgroundCommand.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/modules/MapModulesBackgroundCommand.java @@ -20,11 +20,11 @@ import java.util.Collection; import ghidra.app.services.DebuggerStaticMappingService; import ghidra.debug.api.modules.ModuleMapProposal.ModuleMapEntry; import ghidra.framework.cmd.BackgroundCommand; -import ghidra.framework.model.DomainObject; +import ghidra.trace.model.Trace; import ghidra.util.exception.CancelledException; import ghidra.util.task.TaskMonitor; -public class MapModulesBackgroundCommand extends BackgroundCommand { +public class MapModulesBackgroundCommand extends BackgroundCommand { private final DebuggerStaticMappingService service; private final Collection entries; @@ -36,7 +36,7 @@ public class MapModulesBackgroundCommand extends BackgroundCommand { } @Override - public boolean applyTo(DomainObject obj, TaskMonitor monitor) { + public boolean applyTo(Trace trace, TaskMonitor monitor) { try { service.addModuleMappings(entries, monitor, true); } diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/modules/MapRegionsBackgroundCommand.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/modules/MapRegionsBackgroundCommand.java index 32edcb1acc..700c6a5c3d 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/modules/MapRegionsBackgroundCommand.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/modules/MapRegionsBackgroundCommand.java @@ -20,11 +20,11 @@ import java.util.Collection; import ghidra.app.services.DebuggerStaticMappingService; import ghidra.debug.api.modules.RegionMapProposal.RegionMapEntry; import ghidra.framework.cmd.BackgroundCommand; -import ghidra.framework.model.DomainObject; +import ghidra.trace.model.Trace; import ghidra.util.exception.CancelledException; import ghidra.util.task.TaskMonitor; -public class MapRegionsBackgroundCommand extends BackgroundCommand { +public class MapRegionsBackgroundCommand extends BackgroundCommand { private final DebuggerStaticMappingService service; private final Collection entries; @@ -36,7 +36,7 @@ public class MapRegionsBackgroundCommand extends BackgroundCommand { } @Override - public boolean applyTo(DomainObject obj, TaskMonitor monitor) { + public boolean applyTo(Trace trace, TaskMonitor monitor) { try { service.addRegionMappings(entries, monitor, true); } diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/modules/MapSectionsBackgroundCommand.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/modules/MapSectionsBackgroundCommand.java index 88da52fbed..49c4b00625 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/modules/MapSectionsBackgroundCommand.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/modules/MapSectionsBackgroundCommand.java @@ -20,11 +20,11 @@ import java.util.Collection; import ghidra.app.services.DebuggerStaticMappingService; import ghidra.debug.api.modules.SectionMapProposal.SectionMapEntry; import ghidra.framework.cmd.BackgroundCommand; -import ghidra.framework.model.DomainObject; +import ghidra.trace.model.Trace; import ghidra.util.exception.CancelledException; import ghidra.util.task.TaskMonitor; -public class MapSectionsBackgroundCommand extends BackgroundCommand { +public class MapSectionsBackgroundCommand extends BackgroundCommand { private final DebuggerStaticMappingService service; private final Collection entries; @@ -36,7 +36,7 @@ public class MapSectionsBackgroundCommand extends BackgroundCommand { } @Override - public boolean applyTo(DomainObject obj, TaskMonitor monitor) { + public boolean applyTo(Trace trace, TaskMonitor monitor) { try { service.addSectionMappings(entries, monitor, true); } diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/stack/UnwindStackCommand.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/stack/UnwindStackCommand.java index ca68a448c3..3d6e002736 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/stack/UnwindStackCommand.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/stack/UnwindStackCommand.java @@ -16,7 +16,7 @@ package ghidra.app.plugin.core.debug.stack; import ghidra.debug.api.tracemgr.DebuggerCoordinates; -import ghidra.framework.cmd.TypedBackgroundCommand; +import ghidra.framework.cmd.BackgroundCommand; import ghidra.framework.plugintool.PluginTool; import ghidra.pcode.exec.DebuggerPcodeUtils.WatchValue; import ghidra.trace.model.Trace; @@ -27,7 +27,7 @@ import ghidra.util.task.TaskMonitor; * A command to unwind as much of the stack as possible and annotate the resulting frame in the * dynamic listing */ -public class UnwindStackCommand extends TypedBackgroundCommand { +public class UnwindStackCommand extends BackgroundCommand { private final PluginTool tool; private final DebuggerCoordinates where; @@ -39,7 +39,7 @@ public class UnwindStackCommand extends TypedBackgroundCommand { } @Override - public boolean applyToTyped(Trace obj, TaskMonitor monitor) { + public boolean applyTo(Trace obj, TaskMonitor monitor) { try { StackUnwinder unwinder = new StackUnwinder(tool, where.getPlatform()); int prevParamSize = 0; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/utils/BackgroundUtils.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/utils/BackgroundUtils.java index 0b7db5ce97..dde7f01ec0 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/utils/BackgroundUtils.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/utils/BackgroundUtils.java @@ -25,7 +25,6 @@ import org.apache.commons.lang3.exception.ExceptionUtils; import ghidra.async.AsyncUtils; import ghidra.framework.cmd.BackgroundCommand; import ghidra.framework.model.DomainObject; -import ghidra.framework.model.UndoableDomainObject; import ghidra.framework.plugintool.PluginTool; import ghidra.util.Msg; import ghidra.util.Swing; @@ -35,8 +34,8 @@ import ghidra.util.task.*; public enum BackgroundUtils { ; - public static class AsyncBackgroundCommand - extends BackgroundCommand { + public static class AsyncBackgroundCommand + extends BackgroundCommand { private CompletableFuture promise; private final CancelledListener cancelledListener = this::cancelled; @@ -53,9 +52,8 @@ public enum BackgroundUtils { } @Override - @SuppressWarnings("unchecked") - public boolean applyTo(DomainObject obj, TaskMonitor monitor) { - promise = futureProducer.apply((T) obj, monitor); + public boolean applyTo(T obj, TaskMonitor monitor) { + promise = futureProducer.apply(obj, monitor); monitor.addCancelledListener(cancelledListener); try { promise.get(); @@ -103,8 +101,8 @@ public enum BackgroundUtils { * @param futureProducer a function to start the task * @return a future which completes when the task is finished. */ - public static AsyncBackgroundCommand async(PluginTool tool, - T obj, String name, boolean hasProgress, boolean canCancel, boolean isModal, + public static AsyncBackgroundCommand async(PluginTool tool, T obj, + String name, boolean hasProgress, boolean canCancel, boolean isModal, BiFunction> futureProducer) { AsyncBackgroundCommand cmd = new AsyncBackgroundCommand<>(name, hasProgress, canCancel, isModal, futureProducer); @@ -119,7 +117,7 @@ public enum BackgroundUtils { * The returned future includes error handling, so even if the task completes in error, the * returned future will just complete with null. If further error handling is required, then the * {@code futureProducer} should make the future available. This differs from - * {@link #async(PluginTool, UndoableDomainObject, String, boolean, boolean, boolean, BiFunction)} + * {@link #async(PluginTool, DomainObject, String, boolean, boolean, boolean, BiFunction)} * in that it doesn't use the tool's task manager, so it can run in parallel with other tasks. * There is not currently a supported method to run multiple non-modal tasks concurrently, since * they would have to share a single task monitor component. @@ -172,14 +170,14 @@ public enum BackgroundUtils { private final PluginTool tool; private final String name; - private final UndoableDomainObject obj; + private final DomainObject obj; private final int delay; private final EnumSet opts; private TaskMonitor lastMonitor; - public PluginToolExecutorService(PluginTool tool, String name, UndoableDomainObject obj, - int delay, TaskOpt... opts) { + public PluginToolExecutorService(PluginTool tool, String name, DomainObject obj, int delay, + TaskOpt... opts) { this.tool = tool; this.name = name; this.obj = obj; @@ -223,10 +221,8 @@ public enum BackgroundUtils { } protected void executeForeground(Runnable command) { - Task task = new Task(name, - opts.contains(TaskOpt.CAN_CANCEL), - opts.contains(TaskOpt.HAS_PROGRESS), - opts.contains(TaskOpt.IS_MODAL)) { + Task task = new Task(name, opts.contains(TaskOpt.CAN_CANCEL), + opts.contains(TaskOpt.HAS_PROGRESS), opts.contains(TaskOpt.IS_MODAL)) { @Override public void run(TaskMonitor monitor) throws CancelledException { lastMonitor = monitor; @@ -237,10 +233,8 @@ public enum BackgroundUtils { } protected void executeBackground(Runnable command) { - BackgroundCommand cmd = new BackgroundCommand(name, - opts.contains(TaskOpt.HAS_PROGRESS), - opts.contains(TaskOpt.CAN_CANCEL), - opts.contains(TaskOpt.IS_MODAL)) { + BackgroundCommand cmd = new BackgroundCommand(name, opts.contains(TaskOpt.HAS_PROGRESS), + opts.contains(TaskOpt.CAN_CANCEL), opts.contains(TaskOpt.IS_MODAL)) { @Override public boolean applyTo(DomainObject obj, TaskMonitor monitor) { lastMonitor = monitor; diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/utils/DefaultTransactionCoalescer.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/utils/DefaultTransactionCoalescer.java index eded120b81..9586df15f9 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/utils/DefaultTransactionCoalescer.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/utils/DefaultTransactionCoalescer.java @@ -17,10 +17,10 @@ package ghidra.app.plugin.core.debug.utils; import ghidra.async.AsyncDebouncer; import ghidra.async.AsyncTimer; -import ghidra.framework.model.UndoableDomainObject; +import ghidra.framework.model.DomainObject; import ghidra.util.Msg; -public class DefaultTransactionCoalescer +public class DefaultTransactionCoalescer implements TransactionCoalescer { protected class Coalescer { diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/utils/TransactionCoalescer.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/utils/TransactionCoalescer.java index 1509fd798c..74b90bdbfa 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/utils/TransactionCoalescer.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/utils/TransactionCoalescer.java @@ -17,11 +17,10 @@ package ghidra.app.plugin.core.debug.utils; import java.util.function.BiFunction; -import ghidra.framework.model.UndoableDomainObject; +import ghidra.framework.model.DomainObject; public interface TransactionCoalescer { - public interface TxFactory - extends BiFunction { + public interface TxFactory extends BiFunction { } public interface CoalescedTx extends AutoCloseable { diff --git a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/disassemble/DebuggerDisassemblyTest.java b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/disassemble/DebuggerDisassemblyTest.java index 84c4f3be3b..86c149b2f5 100644 --- a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/disassemble/DebuggerDisassemblyTest.java +++ b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/disassemble/DebuggerDisassemblyTest.java @@ -197,9 +197,8 @@ public class DebuggerDisassemblyTest extends AbstractGhidraHeadedDebuggerTest { DBTraceMemoryManager memory = tb.trace.getMemoryManager(); if (pcInStack) { - DBTraceObject objFrame = - objects.createObject( - TraceObjectKeyPath.parse("Targets[0].Threads[0].Stack[0]")); + DBTraceObject objFrame = objects + .createObject(TraceObjectKeyPath.parse("Targets[0].Threads[0].Stack[0]")); objFrame.insert(zeroOn, ConflictResolution.DENY); TraceObjectStackFrame frame = objFrame.queryInterface(TraceObjectStackFrame.class); frame.setProgramCounter(zeroOn, tb.addr(offset)); @@ -208,8 +207,8 @@ public class DebuggerDisassemblyTest extends AbstractGhidraHeadedDebuggerTest { objects.createObject( TraceObjectKeyPath.parse("Targets[0].Threads[0].Stack[0].Registers")) .insert(zeroOn, ConflictResolution.DENY); - TraceObjectThread thread = objects.getObjectByCanonicalPath( - TraceObjectKeyPath.parse("Targets[0].Threads[0]")) + TraceObjectThread thread = objects + .getObjectByCanonicalPath(TraceObjectKeyPath.parse("Targets[0].Threads[0]")) .queryInterface(TraceObjectThread.class); traceManager.activateThread(thread); DBTraceMemorySpace regs = @@ -248,8 +247,8 @@ public class DebuggerDisassemblyTest extends AbstractGhidraHeadedDebuggerTest { } } - protected void createLegacyTrace(String langID, long offset, - Supplier byteSupplier) throws Throwable { + protected void createLegacyTrace(String langID, long offset, Supplier byteSupplier) + throws Throwable { createAndOpenTrace(langID); try (Transaction tx = tb.startTransaction()) { @@ -358,8 +357,8 @@ public class DebuggerDisassemblyTest extends AbstractGhidraHeadedDebuggerTest { try (Transaction tx = program.openTransaction("Load")) { start = program.getAddressFactory().getDefaultAddressSpace().getAddress(0x00400000); program.getMemory() - .createInitializedBlock(".text", start, - new ByteArrayInputStream(arr("ebffc0")), 3, monitor, false); + .createInitializedBlock(".text", start, new ByteArrayInputStream(arr("ebffc0")), + 3, monitor, false); } intoProject(program); @@ -654,7 +653,7 @@ public class DebuggerDisassemblyTest extends AbstractGhidraHeadedDebuggerTest { new AddressSet(start, start.addWrap(1))); dis.setInitialContext(DebuggerDisassemblerPlugin.deriveAlternativeDefaultContext( tb.language, new LanguageID("ARM:LE:32:v8T"), start)); - dis.applyToTyped(tb.trace.getProgramView(), TaskMonitor.DUMMY); + dis.applyTo(tb.trace.getProgramView(), TaskMonitor.DUMMY); } waitForDomainObject(tb.trace); @@ -715,11 +714,11 @@ public class DebuggerDisassemblyTest extends AbstractGhidraHeadedDebuggerTest { TraceGuestPlatform guest = Unique.assertOne(tb.trace.getPlatformManager().getGuestPlatforms()); try (Transaction tx = tb.startTransaction()) { - TraceDisassembleCommand dis = new TraceDisassembleCommand(guest, start, - new AddressSet(start, start.addWrap(1))); + TraceDisassembleCommand dis = + new TraceDisassembleCommand(guest, start, new AddressSet(start, start.addWrap(1))); dis.setInitialContext(DebuggerDisassemblerPlugin.deriveAlternativeDefaultContext( guest.getLanguage(), new LanguageID("ARM:LE:32:v8T"), start)); - dis.applyToTyped(tb.trace.getProgramView(), TaskMonitor.DUMMY); + dis.applyTo(tb.trace.getProgramView(), TaskMonitor.DUMMY); } waitForDomainObject(tb.trace); diff --git a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/stack/StackUnwinderTest.java b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/stack/StackUnwinderTest.java index 072a300117..1951b23f92 100644 --- a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/stack/StackUnwinderTest.java +++ b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/stack/StackUnwinderTest.java @@ -190,8 +190,7 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest { function.updateFunction("__cdecl", new ReturnParameterImpl(IntegerDataType.dataType, program), - List.of( - new ParameterImpl("n", IntegerDataType.dataType, program)), + List.of(new ParameterImpl("n", IntegerDataType.dataType, program)), FunctionUpdateType.DYNAMIC_STORAGE_FORMAL_PARAMS, true, SourceType.ANALYSIS); function.addLocalVariable( new LocalVariableImpl("i", IntegerDataType.dataType, -8, program), @@ -263,14 +262,12 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest { function.updateFunction("__cdecl", new ReturnParameterImpl(UnsignedIntegerDataType.dataType, program), - List.of( - new ParameterImpl("n", UnsignedIntegerDataType.dataType, program)), + List.of(new ParameterImpl("n", UnsignedIntegerDataType.dataType, program)), FunctionUpdateType.DYNAMIC_STORAGE_FORMAL_PARAMS, true, SourceType.ANALYSIS); // NOTE: The decompiler doesn't actually use sum.... For some reason, it re-uses n // Still, in the tests, I can use uVar1 (EAX) as a register variable - function.addLocalVariable( - new LocalVariableImpl("sum", 0, UnsignedIntegerDataType.dataType, register("EDX"), - program), + function.addLocalVariable(new LocalVariableImpl("sum", 0, + UnsignedIntegerDataType.dataType, register("EDX"), program), SourceType.USER_DEFINED); Instruction ins = program.getListing().getInstructionAt(stackRefInstr); @@ -501,18 +498,15 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest { .createFunction("fillStruct", funcInstr, new AddressSet(funcInstr, end.previous()), SourceType.USER_DEFINED); funFillStruct.updateFunction("__cdecl", null, - List.of( - new ParameterImpl("s", new PointerDataType(structure), program)), + List.of(new ParameterImpl("s", new PointerDataType(structure), program)), FunctionUpdateType.DYNAMIC_STORAGE_FORMAL_PARAMS, true, SourceType.ANALYSIS); Function main = program.getFunctionManager() .createFunction("main", entry, new AddressSet(entry, funcInstr.previous()), SourceType.USER_DEFINED); - main.updateFunction("__cdecl", - new ReturnParameterImpl(DWordDataType.dataType, program), + main.updateFunction("__cdecl", new ReturnParameterImpl(DWordDataType.dataType, program), FunctionUpdateType.DYNAMIC_STORAGE_FORMAL_PARAMS, true, SourceType.ANALYSIS); - main.addLocalVariable( - new LocalVariableImpl("myStack", structure, -8, program), + main.addLocalVariable(new LocalVariableImpl("myStack", structure, -8, program), SourceType.ANALYSIS); return main; } @@ -581,16 +575,14 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest { .createFunction("fillStruct", funcInstr, new AddressSet(funcInstr, end.previous()), SourceType.USER_DEFINED); funFillStruct.updateFunction("__cdecl", null, - List.of( - new ParameterImpl("s", new PointerDataType(structure), program), + List.of(new ParameterImpl("s", new PointerDataType(structure), program), new ParameterImpl("i", IntegerDataType.dataType, program)), FunctionUpdateType.DYNAMIC_STORAGE_FORMAL_PARAMS, true, SourceType.ANALYSIS); Function main = program.getFunctionManager() .createFunction("main", entry, new AddressSet(entry, funcInstr.previous()), SourceType.USER_DEFINED); - main.updateFunction("__cdecl", - new ReturnParameterImpl(DWordDataType.dataType, program), + main.updateFunction("__cdecl", new ReturnParameterImpl(DWordDataType.dataType, program), FunctionUpdateType.DYNAMIC_STORAGE_FORMAL_PARAMS, true, SourceType.ANALYSIS); return main; } @@ -614,10 +606,7 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest { UnwindInfo infoAtBody = ua.computeUnwindInfo(bodyInstr, monitor); assertEquals(new UnwindInfo(function, -20L, 4L, stack(0), - Map.of( - register("EBP"), stack(-4)), - new StackUnwindWarningSet(), null), - infoAtBody); + Map.of(register("EBP"), stack(-4)), new StackUnwindWarningSet(), null), infoAtBody); } @Test @@ -640,13 +629,11 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest { infoAtEntry); UnwindInfo infoAtBody = ua.computeUnwindInfo(bodyInstr, monitor); - assertEquals(new UnwindInfo(function, -20L, 4L, stack(0), - Map.of( - register("EBP"), stack(-4)), - new StackUnwindWarningSet( - new UnspecifiedConventionStackUnwindWarning(myExtern), - new UnknownPurgeStackUnwindWarning(myExtern)), - null), + assertEquals( + new UnwindInfo(function, -20L, 4L, stack(0), Map.of(register("EBP"), stack(-4)), + new StackUnwindWarningSet(new UnspecifiedConventionStackUnwindWarning(myExtern), + new UnknownPurgeStackUnwindWarning(myExtern)), + null), infoAtBody); } @@ -670,11 +657,8 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest { UnwindInfo infoAtBody = ua.computeUnwindInfo(bodyInstr, monitor); DataType ptr2Undef = new PointerDataType(DataType.DEFAULT, program.getDataTypeManager()); assertEquals(new UnwindInfo(function, -20L, 4L, stack(0), - Map.of( - register("EBP"), stack(-4)), - new StackUnwindWarningSet( - new UnexpectedTargetTypeStackUnwindWarning(ptr2Undef)), - null), + Map.of(register("EBP"), stack(-4)), + new StackUnwindWarningSet(new UnexpectedTargetTypeStackUnwindWarning(ptr2Undef)), null), infoAtBody); } @@ -684,8 +668,7 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest { addPlugin(tool, DebuggerListingPlugin.class); addPlugin(tool, DisassemblerPlugin.class); addPlugin(tool, DecompilePlugin.class); - DebuggerControlService editingService = - addPlugin(tool, DebuggerControlServicePlugin.class); + DebuggerControlService editingService = addPlugin(tool, DebuggerControlServicePlugin.class); DebuggerEmulationService emuService = addPlugin(tool, DebuggerEmulationServicePlugin.class); Function function = createSumSquaresProgramX86_32(); @@ -744,8 +727,7 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest { addPlugin(tool, DebuggerListingPlugin.class); addPlugin(tool, DisassemblerPlugin.class); addPlugin(tool, DecompilePlugin.class); - DebuggerControlService editingService = - addPlugin(tool, DebuggerControlServicePlugin.class); + DebuggerControlService editingService = addPlugin(tool, DebuggerControlServicePlugin.class); DebuggerEmulationService emuService = addPlugin(tool, DebuggerEmulationServicePlugin.class); Function function = createFibonacciProgramX86_32(); @@ -775,13 +757,12 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest { TraceBreakpoint bptUnwind; try (Transaction tx = tb.startTransaction()) { bptUnwind = tb.trace.getBreakpointManager() - .addBreakpoint("Breakpoints[0]", Lifespan.nowOn(0), retInstr, - Set.of(), + .addBreakpoint("Breakpoints[0]", Lifespan.nowOn(0), retInstr, Set.of(), Set.of(TraceBreakpointKind.SW_EXECUTE), true, "unwind stack"); tb.trace.getBreakpointManager() .addBreakpoint("Breakpoints[1]", Lifespan.nowOn(0), tb.addr(0xdeadbeef), - Set.of(), - Set.of(TraceBreakpointKind.SW_EXECUTE), true, "capture return value"); + Set.of(), Set.of(TraceBreakpointKind.SW_EXECUTE), true, + "capture return value"); } EmulationResult result = emuService.run(atSetup.getPlatform(), atSetup.getTime(), monitor, @@ -916,8 +897,7 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest { try (Transaction tx = tb.startTransaction()) { tb.trace.getBreakpointManager() - .addBreakpoint("Breakpoints[0]", Lifespan.nowOn(0), retInstr, - Set.of(), + .addBreakpoint("Breakpoints[0]", Lifespan.nowOn(0), retInstr, Set.of(), Set.of(TraceBreakpointKind.SW_EXECUTE), true, "unwind stack"); } @@ -957,8 +937,7 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest { try (Transaction tx = tb.startTransaction()) { tb.trace.getBreakpointManager() - .addBreakpoint("Breakpoints[0]", Lifespan.nowOn(0), retInstr, - Set.of(), + .addBreakpoint("Breakpoints[0]", Lifespan.nowOn(0), retInstr, Set.of(), Set.of(TraceBreakpointKind.SW_EXECUTE), true, "unwind stack"); } @@ -999,8 +978,7 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest { try (Transaction tx = tb.startTransaction()) { tb.trace.getBreakpointManager() - .addBreakpoint("Breakpoints[0]", Lifespan.nowOn(0), retInstr, - Set.of(), + .addBreakpoint("Breakpoints[0]", Lifespan.nowOn(0), retInstr, Set.of(), Set.of(TraceBreakpointKind.SW_EXECUTE), true, "unwind stack"); } @@ -1041,8 +1019,7 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest { try (Transaction tx = tb.startTransaction()) { tb.trace.getBreakpointManager() - .addBreakpoint("Breakpoints[0]", Lifespan.nowOn(0), retInstr, - Set.of(), + .addBreakpoint("Breakpoints[0]", Lifespan.nowOn(0), retInstr, Set.of(), Set.of(TraceBreakpointKind.SW_EXECUTE), true, "unwind stack"); } @@ -1166,8 +1143,8 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest { FieldLocation fieldLocation, Field field) throws Throwable { VariableValueTable table = new VariableValueTable(); StackUnwindWarningSet warnings = new StackUnwindWarningSet(); - waitOn(valuesService.fillVariableValueTable(table, programLocation, current, - fieldLocation, field, warnings)); + waitOn(valuesService.fillVariableValueTable(table, programLocation, current, fieldLocation, + field, warnings)); table.add(new WarningsRow(warnings)); return table; } @@ -1182,16 +1159,12 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest { VariableValueTable table = getVariableValueTable(valuesService, loc.pLoc, traceManager.getCurrent(), loc.fLoc, loc.field); - assertTable(Map.of( - RowKey.NAME, "Name: n", - RowKey.FRAME, "Frame: 0 fib pc=0040002c sp=00004ff4 base=00004ff4", - RowKey.STORAGE, "Storage: Stack[0x4]:4", - RowKey.TYPE, "Type: uint", - RowKey.LOCATION, "Location: 00004ff8:4", - RowKey.BYTES, "Bytes: (KNOWN) 01 00 00 00", - RowKey.INTEGER, "Integer: (KNOWN) 1", - RowKey.VALUE, "Value: (KNOWN) 1h", - RowKey.WARNINGS, "IGNORED"), table); + assertTable(Map.of(RowKey.NAME, "Name: n", RowKey.FRAME, + "Frame: 0 fib pc=0040002c sp=00004ff4 base=00004ff4", RowKey.STORAGE, + "Storage: Stack[0x4]:4", RowKey.TYPE, "Type: uint", RowKey.LOCATION, + "Location: 00004ff8:4", RowKey.BYTES, "Bytes: (KNOWN) 01 00 00 00", RowKey.INTEGER, + "Integer: (KNOWN) 1", RowKey.VALUE, "Value: (KNOWN) 1h", RowKey.WARNINGS, "IGNORED"), + table); } @Test @@ -1204,15 +1177,11 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest { VariableValueTable table = getVariableValueTable(valuesService, loc.pLoc, traceManager.getCurrent(), loc.fLoc, loc.field); - assertTable(Map.of( - RowKey.NAME, "Name: sum", - RowKey.FRAME, "Frame: 0 fib pc=0040002c sp=00004ff4 base=00004ff4", - RowKey.STORAGE, "Storage: EDX:4", - RowKey.TYPE, "Type: uint", - RowKey.LOCATION, "Location: EDX:4", - RowKey.INTEGER, "Integer: (UNKNOWN) 0", - RowKey.VALUE, "Value: (UNKNOWN) 0h", - RowKey.WARNINGS, "IGNORED"), table); + assertTable(Map.of(RowKey.NAME, "Name: sum", RowKey.FRAME, + "Frame: 0 fib pc=0040002c sp=00004ff4 base=00004ff4", RowKey.STORAGE, "Storage: EDX:4", + RowKey.TYPE, "Type: uint", RowKey.LOCATION, "Location: EDX:4", RowKey.INTEGER, + "Integer: (UNKNOWN) 0", RowKey.VALUE, "Value: (UNKNOWN) 0h", RowKey.WARNINGS, + "IGNORED"), table); } @Test @@ -1225,15 +1194,11 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest { VariableValueTable table = getVariableValueTable(valuesService, loc.pLoc, traceManager.getCurrent(), loc.fLoc, loc.field); - assertTable(Map.of( - RowKey.NAME, "Name: ", - RowKey.FRAME, "Frame: 0 fib pc=0040002c sp=00004ff4 base=00004ff4", - RowKey.STORAGE, "Storage: EAX:4", - RowKey.TYPE, "Type: uint", - RowKey.LOCATION, "Location: EAX:4", - RowKey.INTEGER, "Integer: (KNOWN) 1", - RowKey.VALUE, "Value: (KNOWN) 1h", - RowKey.WARNINGS, "IGNORED"), table); + assertTable(Map.of(RowKey.NAME, "Name: ", RowKey.FRAME, + "Frame: 0 fib pc=0040002c sp=00004ff4 base=00004ff4", RowKey.STORAGE, "Storage: EAX:4", + RowKey.TYPE, "Type: uint", RowKey.LOCATION, "Location: EAX:4", RowKey.INTEGER, + "Integer: (KNOWN) 1", RowKey.VALUE, "Value: (KNOWN) 1h", RowKey.WARNINGS, "IGNORED"), + table); } @Test @@ -1247,16 +1212,11 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest { VariableValueTable table = getVariableValueTable(valuesService, loc.pLoc, traceManager.getCurrent(), loc.fLoc, loc.field); - assertTable(Map.of( - RowKey.NAME, "Name: myGlobal", - RowKey.STORAGE, "Storage: 00600000:4", - RowKey.TYPE, "Type: int", - RowKey.LOCATION, "Location: 00600000:4", - RowKey.BYTES, "Bytes: (KNOWN) ef be ad de", - RowKey.INTEGER, """ + assertTable(Map.of(RowKey.NAME, "Name: myGlobal", RowKey.STORAGE, "Storage: 00600000:4", + RowKey.TYPE, "Type: int", RowKey.LOCATION, "Location: 00600000:4", RowKey.BYTES, + "Bytes: (KNOWN) ef be ad de", RowKey.INTEGER, """ Integer: (KNOWN) 3735928559, 0xdeadbeef - -559038737, -0x21524111""", - RowKey.VALUE, "Value: (KNOWN) DEADBEEFh", + -559038737, -0x21524111""", RowKey.VALUE, "Value: (KNOWN) DEADBEEFh", RowKey.WARNINGS, "IGNORED"), table); } @@ -1269,17 +1229,17 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest { Address dynamicAddress = dynLoc.getAddress(); try (Transaction tx = tb.startTransaction()) { int length = stIns.getLength(); - assertEquals(length, tb.trace.getMemoryManager() - .putBytes(current.getSnap(), dynamicAddress, - ByteBuffer.wrap(stIns.getBytes()))); + assertEquals(length, + tb.trace.getMemoryManager() + .putBytes(current.getSnap(), dynamicAddress, + ByteBuffer.wrap(stIns.getBytes()))); new TraceDisassembleCommand(current.getPlatform(), dynamicAddress, new AddressSet(dynamicAddress, dynamicAddress.add(length - 1))) - .applyToTyped(current.getView(), monitor); + .applyTo(current.getView(), monitor); } waitForDomainObject(tb.trace); - return Objects.requireNonNull(tb.trace.getCodeManager() - .instructions() - .getAt(current.getViewSnap(), dynamicAddress)); + return Objects.requireNonNull( + tb.trace.getCodeManager().instructions().getAt(current.getViewSnap(), dynamicAddress)); } @Test @@ -1295,16 +1255,11 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest { VariableValueTable table = getVariableValueTable(valuesService, loc.pLoc, traceManager.getCurrent(), loc.fLoc, loc.field); - assertTable(Map.of( - RowKey.NAME, "Name: myGlobal", - RowKey.STORAGE, "Storage: 00600000:4", - RowKey.TYPE, "Type: int", - RowKey.LOCATION, "Location: 00600000:4", - RowKey.BYTES, "Bytes: (KNOWN) ef be ad de", - RowKey.INTEGER, """ + assertTable(Map.of(RowKey.NAME, "Name: myGlobal", RowKey.STORAGE, "Storage: 00600000:4", + RowKey.TYPE, "Type: int", RowKey.LOCATION, "Location: 00600000:4", RowKey.BYTES, + "Bytes: (KNOWN) ef be ad de", RowKey.INTEGER, """ Integer: (KNOWN) 3735928559, 0xdeadbeef - -559038737, -0x21524111""", - RowKey.VALUE, "Value: (KNOWN) DEADBEEFh", + -559038737, -0x21524111""", RowKey.VALUE, "Value: (KNOWN) DEADBEEFh", RowKey.WARNINGS, "IGNORED"), table); } @@ -1319,16 +1274,12 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest { VariableValueTable table = getVariableValueTable(valuesService, loc.pLoc, traceManager.getCurrent(), loc.fLoc, loc.field); - assertTable(Map.of( - RowKey.NAME, "Name: n", - RowKey.FRAME, "Frame: 0 fib pc=0040002c sp=00004ff4 base=00004ff4", - RowKey.STORAGE, "Storage: Stack[0x4]:4", - RowKey.TYPE, "Type: uint", - RowKey.LOCATION, "Location: 00004ff8:4", - RowKey.BYTES, "Bytes: (KNOWN) 01 00 00 00", - RowKey.INTEGER, "Integer: (KNOWN) 1", - RowKey.VALUE, "Value: (KNOWN) 1h", - RowKey.WARNINGS, "IGNORED"), table); + assertTable(Map.of(RowKey.NAME, "Name: n", RowKey.FRAME, + "Frame: 0 fib pc=0040002c sp=00004ff4 base=00004ff4", RowKey.STORAGE, + "Storage: Stack[0x4]:4", RowKey.TYPE, "Type: uint", RowKey.LOCATION, + "Location: 00004ff8:4", RowKey.BYTES, "Bytes: (KNOWN) 01 00 00 00", RowKey.INTEGER, + "Integer: (KNOWN) 1", RowKey.VALUE, "Value: (KNOWN) 1h", RowKey.WARNINGS, "IGNORED"), + table); } @Test @@ -1342,15 +1293,11 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest { VariableValueTable table = getVariableValueTable(valuesService, loc.pLoc, traceManager.getCurrent(), loc.fLoc, loc.field); - assertTable(Map.of( - RowKey.NAME, "Name: sum", - RowKey.FRAME, "Frame: 0 fib pc=0040002c sp=00004ff4 base=00004ff4", - RowKey.STORAGE, "Storage: EDX:4", - RowKey.TYPE, "Type: uint", - RowKey.LOCATION, "Location: EDX:4", - RowKey.INTEGER, "Integer: (UNKNOWN) 0", - RowKey.VALUE, "Value: (UNKNOWN) 0h", - RowKey.WARNINGS, "IGNORED"), table); + assertTable(Map.of(RowKey.NAME, "Name: sum", RowKey.FRAME, + "Frame: 0 fib pc=0040002c sp=00004ff4 base=00004ff4", RowKey.STORAGE, "Storage: EDX:4", + RowKey.TYPE, "Type: uint", RowKey.LOCATION, "Location: EDX:4", RowKey.INTEGER, + "Integer: (UNKNOWN) 0", RowKey.VALUE, "Value: (UNKNOWN) 0h", RowKey.WARNINGS, + "IGNORED"), table); } @Test @@ -1367,11 +1314,9 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest { VariableValueTable table = getVariableValueTable(valuesService, loc.pLoc, traceManager.getCurrent(), loc.fLoc, loc.field); - assertTable(Map.of( - RowKey.NAME, "Name: EBP", - RowKey.FRAME, "Frame: 2 fib pc=00400013 sp=00004ff8 base=00005000", - RowKey.LOCATION, "Location: 00004ff0:4", - RowKey.INTEGER, "Integer: (KNOWN) 20476, 0x4ffc", + assertTable(Map.of(RowKey.NAME, "Name: EBP", RowKey.FRAME, + "Frame: 2 fib pc=00400013 sp=00004ff8 base=00005000", RowKey.LOCATION, + "Location: 00004ff0:4", RowKey.INTEGER, "Integer: (KNOWN) 20476, 0x4ffc", RowKey.WARNINGS, "IGNORED"), table); } @@ -1388,9 +1333,7 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest { VariableValueTable table = getVariableValueTable(valuesService, loc.pLoc, traceManager.getCurrent(), loc.fLoc, loc.field); - assertTable(Map.of( - RowKey.NAME, "Name: EDX", - RowKey.INTEGER, "Integer: (UNKNOWN) 0", + assertTable(Map.of(RowKey.NAME, "Name: EDX", RowKey.INTEGER, "Integer: (UNKNOWN) 0", RowKey.WARNINGS, "IGNORED"), table); } @@ -1495,16 +1438,11 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest { VariableValueTable table = getVariableValueTable(valuesService, loc.pLoc, traceManager.getCurrent(), loc.fLoc, loc.field); - assertTable(Map.of( - RowKey.NAME, "Name: myGlobal", - RowKey.STORAGE, "Storage: 00600000:4", - RowKey.TYPE, "Type: int", - RowKey.LOCATION, "Location: 00600000:4", - RowKey.BYTES, "Bytes: (KNOWN) ef be ad de", - RowKey.INTEGER, """ + assertTable(Map.of(RowKey.NAME, "Name: myGlobal", RowKey.STORAGE, "Storage: 00600000:4", + RowKey.TYPE, "Type: int", RowKey.LOCATION, "Location: 00600000:4", RowKey.BYTES, + "Bytes: (KNOWN) ef be ad de", RowKey.INTEGER, """ Integer: (KNOWN) 3735928559, 0xdeadbeef - -559038737, -0x21524111""", - RowKey.VALUE, "Value: (KNOWN) DEADBEEFh", + -559038737, -0x21524111""", RowKey.VALUE, "Value: (KNOWN) DEADBEEFh", RowKey.WARNINGS, "IGNORED"), table); } @@ -1518,16 +1456,12 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest { VariableValueTable table = getVariableValueTable(valuesService, loc.pLoc, traceManager.getCurrent(), loc.fLoc, loc.field); - assertTable(Map.of( - RowKey.NAME, "Name: n", - RowKey.FRAME, "Frame: 0 fib pc=0040002c sp=00004ff4 base=00004ff4", - RowKey.STORAGE, "Storage: Stack[0x4]:4", - RowKey.TYPE, "Type: uint", - RowKey.LOCATION, "Location: 00004ff8:4", - RowKey.BYTES, "Bytes: (KNOWN) 01 00 00 00", - RowKey.INTEGER, "Integer: (KNOWN) 1", - RowKey.VALUE, "Value: (KNOWN) 1h", - RowKey.WARNINGS, "IGNORED"), table); + assertTable(Map.of(RowKey.NAME, "Name: n", RowKey.FRAME, + "Frame: 0 fib pc=0040002c sp=00004ff4 base=00004ff4", RowKey.STORAGE, + "Storage: Stack[0x4]:4", RowKey.TYPE, "Type: uint", RowKey.LOCATION, + "Location: 00004ff8:4", RowKey.BYTES, "Bytes: (KNOWN) 01 00 00 00", RowKey.INTEGER, + "Integer: (KNOWN) 1", RowKey.VALUE, "Value: (KNOWN) 1h", RowKey.WARNINGS, "IGNORED"), + table); } @Test @@ -1541,15 +1475,11 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest { VariableValueTable table = getVariableValueTable(valuesService, loc.pLoc, traceManager.getCurrent(), loc.fLoc, loc.field); - assertTable(Map.of( - RowKey.NAME, "Name: uVar1", - RowKey.FRAME, "Frame: 0 fib pc=0040002c sp=00004ff4 base=00004ff4", - RowKey.STORAGE, "Storage: EAX:4", - RowKey.TYPE, "Type: uint", - RowKey.LOCATION, "Location: EAX:4", - RowKey.INTEGER, "Integer: (KNOWN) 1", - RowKey.VALUE, "Value: (KNOWN) 1h", - RowKey.WARNINGS, "IGNORED"), table); + assertTable(Map.of(RowKey.NAME, "Name: uVar1", RowKey.FRAME, + "Frame: 0 fib pc=0040002c sp=00004ff4 base=00004ff4", RowKey.STORAGE, "Storage: EAX:4", + RowKey.TYPE, "Type: uint", RowKey.LOCATION, "Location: EAX:4", RowKey.INTEGER, + "Integer: (KNOWN) 1", RowKey.VALUE, "Value: (KNOWN) 1h", RowKey.WARNINGS, "IGNORED"), + table); } @Test @@ -1566,15 +1496,10 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest { VariableValueTable table = getVariableValueTable(valuesService, loc.pLoc, traceManager.getCurrent(), loc.fLoc, loc.field); - assertTable(Map.of( - RowKey.NAME, "Name: myGlobal", - RowKey.STORAGE, "Storage: 00600000:4", - RowKey.TYPE, "Type: MyStruct", - RowKey.LOCATION, "Location: 00600000:4", - RowKey.BYTES, "Bytes: (KNOWN) e6 07 0c 09", - RowKey.INTEGER, "Integer: (KNOWN) 151783398, 0x90c07e6", - RowKey.VALUE, "Value: (KNOWN) ", - RowKey.WARNINGS, "IGNORED"), table); + assertTable(Map.of(RowKey.NAME, "Name: myGlobal", RowKey.STORAGE, "Storage: 00600000:4", + RowKey.TYPE, "Type: MyStruct", RowKey.LOCATION, "Location: 00600000:4", RowKey.BYTES, + "Bytes: (KNOWN) e6 07 0c 09", RowKey.INTEGER, "Integer: (KNOWN) 151783398, 0x90c07e6", + RowKey.VALUE, "Value: (KNOWN) ", RowKey.WARNINGS, "IGNORED"), table); } @Test @@ -1591,14 +1516,10 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest { VariableValueTable table = getVariableValueTable(valuesService, loc.pLoc, traceManager.getCurrent(), loc.fLoc, loc.field); - assertTable(Map.of( - RowKey.NAME, "Name: m", - RowKey.TYPE, "Type: byte", - RowKey.LOCATION, "Location: 00600002:1", - RowKey.BYTES, "Bytes: (KNOWN) 0c", - RowKey.INTEGER, "Integer: (KNOWN) 12, 0xc", - RowKey.VALUE, "Value: (KNOWN) Ch", - RowKey.WARNINGS, "IGNORED"), table); + assertTable(Map.of(RowKey.NAME, "Name: m", RowKey.TYPE, "Type: byte", RowKey.LOCATION, + "Location: 00600002:1", RowKey.BYTES, "Bytes: (KNOWN) 0c", RowKey.INTEGER, + "Integer: (KNOWN) 12, 0xc", RowKey.VALUE, "Value: (KNOWN) Ch", RowKey.WARNINGS, + "IGNORED"), table); } @Test @@ -1615,16 +1536,12 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest { VariableValueTable table = getVariableValueTable(valuesService, loc.pLoc, traceManager.getCurrent(), loc.fLoc, loc.field); - assertTable(Map.of( - RowKey.NAME, "Name: myStack", - RowKey.FRAME, "Frame: 1 main pc=00400012 sp=00004fe4 base=00004ff0", - RowKey.STORAGE, "Storage: Stack[-0x8]:4", - RowKey.TYPE, "Type: MyStruct", - RowKey.LOCATION, "Location: 00004fe8:4", - RowKey.BYTES, "Bytes: (UNKNOWN) 00 00 00 00", - RowKey.INTEGER, "Integer: (UNKNOWN) 0", - RowKey.VALUE, "Value: (UNKNOWN) ", - RowKey.WARNINGS, "IGNORED"), table); + assertTable(Map.of(RowKey.NAME, "Name: myStack", RowKey.FRAME, + "Frame: 1 main pc=00400012 sp=00004fe4 base=00004ff0", RowKey.STORAGE, + "Storage: Stack[-0x8]:4", RowKey.TYPE, "Type: MyStruct", RowKey.LOCATION, + "Location: 00004fe8:4", RowKey.BYTES, "Bytes: (UNKNOWN) 00 00 00 00", RowKey.INTEGER, + "Integer: (UNKNOWN) 0", RowKey.VALUE, "Value: (UNKNOWN) ", RowKey.WARNINGS, "IGNORED"), + table); } @Test @@ -1641,14 +1558,10 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest { VariableValueTable table = getVariableValueTable(valuesService, loc.pLoc, traceManager.getCurrent(), loc.fLoc, loc.field); - assertTable(Map.of( - RowKey.NAME, "Name: y", - RowKey.FRAME, "Frame: 1 main pc=00400012 sp=00004fe4 base=00004ff0", - RowKey.TYPE, "Type: word", - RowKey.LOCATION, "Location: 00004fe8:2", - RowKey.BYTES, "Bytes: (UNKNOWN) 00 00", - RowKey.INTEGER, "Integer: (UNKNOWN) 0", - RowKey.VALUE, "Value: (UNKNOWN) 0h", + assertTable(Map.of(RowKey.NAME, "Name: y", RowKey.FRAME, + "Frame: 1 main pc=00400012 sp=00004fe4 base=00004ff0", RowKey.TYPE, "Type: word", + RowKey.LOCATION, "Location: 00004fe8:2", RowKey.BYTES, "Bytes: (UNKNOWN) 00 00", + RowKey.INTEGER, "Integer: (UNKNOWN) 0", RowKey.VALUE, "Value: (UNKNOWN) 0h", RowKey.WARNINGS, "IGNORED"), table); } @@ -1666,16 +1579,13 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest { VariableValueTable table = getVariableValueTable(valuesService, loc.pLoc, traceManager.getCurrent(), loc.fLoc, loc.field); - assertTable(Map.of( - RowKey.NAME, "Name: s", - RowKey.FRAME, "Frame: 0 fillStruct pc=00400041 sp=00004fe0 base=00004fe0", - RowKey.STORAGE, "Storage: Stack[0x4]:4", - RowKey.TYPE, "Type: MyStruct *", - RowKey.LOCATION, "Location: 00004fe4:4", + assertTable(Map.of(RowKey.NAME, "Name: s", RowKey.FRAME, + "Frame: 0 fillStruct pc=00400041 sp=00004fe0 base=00004fe0", RowKey.STORAGE, + "Storage: Stack[0x4]:4", RowKey.TYPE, "Type: MyStruct *", RowKey.LOCATION, + "Location: 00004fe4:4", // NOTE: Value is the pointer, not the struct - RowKey.BYTES, "Bytes: (KNOWN) 00 00 60 00", - RowKey.INTEGER, "Integer: (KNOWN) 6291456, 0x600000", - RowKey.VALUE, "Value: (KNOWN) 00600000", + RowKey.BYTES, "Bytes: (KNOWN) 00 00 60 00", RowKey.INTEGER, + "Integer: (KNOWN) 6291456, 0x600000", RowKey.VALUE, "Value: (KNOWN) 00600000", RowKey.WARNINGS, "IGNORED"), table); } @@ -1693,14 +1603,10 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest { VariableValueTable table = getVariableValueTable(valuesService, loc.pLoc, traceManager.getCurrent(), loc.fLoc, loc.field); - assertTable(Map.of( - RowKey.NAME, "Name: y", - RowKey.FRAME, "Frame: 0 fillStruct pc=00400041 sp=00004fe0 base=00004fe0", - RowKey.TYPE, "Type: word", - RowKey.LOCATION, "Location: 00600000:2", - RowKey.BYTES, "Bytes: (KNOWN) e6 07", - RowKey.INTEGER, "Integer: (KNOWN) 2022, 0x7e6", - RowKey.VALUE, "Value: (KNOWN) 7E6h", + assertTable(Map.of(RowKey.NAME, "Name: y", RowKey.FRAME, + "Frame: 0 fillStruct pc=00400041 sp=00004fe0 base=00004fe0", RowKey.TYPE, "Type: word", + RowKey.LOCATION, "Location: 00600000:2", RowKey.BYTES, "Bytes: (KNOWN) e6 07", + RowKey.INTEGER, "Integer: (KNOWN) 2022, 0x7e6", RowKey.VALUE, "Value: (KNOWN) 7E6h", RowKey.WARNINGS, "IGNORED"), table); } @@ -1718,14 +1624,10 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest { VariableValueTable table = getVariableValueTable(valuesService, loc.pLoc, traceManager.getCurrent(), loc.fLoc, loc.field); - assertTable(Map.of( - RowKey.NAME, "Name: m", - RowKey.FRAME, "Frame: 0 fillStruct pc=0040002e sp=00004fe0 base=00004fe0", - RowKey.TYPE, "Type: byte", - RowKey.LOCATION, "Location: 0060000a:1", - RowKey.BYTES, "Bytes: (KNOWN) 0c", - RowKey.INTEGER, "Integer: (KNOWN) 12, 0xc", - RowKey.VALUE, "Value: (KNOWN) Ch", + assertTable(Map.of(RowKey.NAME, "Name: m", RowKey.FRAME, + "Frame: 0 fillStruct pc=0040002e sp=00004fe0 base=00004fe0", RowKey.TYPE, "Type: byte", + RowKey.LOCATION, "Location: 0060000a:1", RowKey.BYTES, "Bytes: (KNOWN) 0c", + RowKey.INTEGER, "Integer: (KNOWN) 12, 0xc", RowKey.VALUE, "Value: (KNOWN) Ch", RowKey.WARNINGS, "IGNORED"), table); } diff --git a/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/framework/cmd/TypedBackgroundCommand.java b/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/framework/cmd/TypedBackgroundCommand.java deleted file mode 100644 index b5ff519b3b..0000000000 --- a/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/framework/cmd/TypedBackgroundCommand.java +++ /dev/null @@ -1,42 +0,0 @@ -/* ### - * IP: GHIDRA - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ghidra.framework.cmd; - -import ghidra.framework.model.DomainObject; -import ghidra.framework.model.UndoableDomainObject; -import ghidra.framework.plugintool.PluginTool; -import ghidra.util.task.TaskMonitor; - -public abstract class TypedBackgroundCommand - extends BackgroundCommand { - - public TypedBackgroundCommand(String name, boolean hasProgress, boolean canCancel, - boolean isModal) { - super(name, hasProgress, canCancel, isModal); - } - - @Override - @SuppressWarnings("unchecked") - public boolean applyTo(DomainObject obj, TaskMonitor monitor) { - return applyToTyped((T) obj, monitor); - } - - public abstract boolean applyToTyped(T obj, TaskMonitor monitor); - - public void run(PluginTool tool, T obj) { - tool.executeBackgroundCommand(this, obj); - } -} diff --git a/Ghidra/Extensions/sample/src/main/java/ghidra/examples/SampleProgramTreePlugin.java b/Ghidra/Extensions/sample/src/main/java/ghidra/examples/SampleProgramTreePlugin.java index 1034c64285..30809f8ee3 100644 --- a/Ghidra/Extensions/sample/src/main/java/ghidra/examples/SampleProgramTreePlugin.java +++ b/Ghidra/Extensions/sample/src/main/java/ghidra/examples/SampleProgramTreePlugin.java @@ -23,7 +23,6 @@ import ghidra.app.cmd.module.CreateDefaultTreeCmd; import ghidra.app.plugin.PluginCategoryNames; import ghidra.app.plugin.ProgramPlugin; import ghidra.framework.cmd.BackgroundCommand; -import ghidra.framework.model.DomainObject; import ghidra.framework.plugintool.PluginInfo; import ghidra.framework.plugintool.PluginTool; import ghidra.framework.plugintool.util.PluginStatus; @@ -53,7 +52,6 @@ import ghidra.util.task.TaskMonitor; ) //@formatter:on public class SampleProgramTreePlugin extends ProgramPlugin { - private Listing listing; /** * Construct a new SampleProgramTreePlugin. @@ -90,8 +88,7 @@ public class SampleProgramTreePlugin extends ProgramPlugin { * Method Modularize. */ private void modularize() { - BackgroundCommand cmd = new ModularizeCommand(); - + ModularizeCommand cmd = new ModularizeCommand(); tool.executeBackgroundCommand(cmd, currentProgram); } @@ -99,7 +96,7 @@ public class SampleProgramTreePlugin extends ProgramPlugin { * Background command that will create the new tree and organize it. * */ - class ModularizeCommand extends BackgroundCommand { + static class ModularizeCommand extends BackgroundCommand { private int fragment_count = 0; private String programTreeName = "Sample Tree"; @@ -108,10 +105,9 @@ public class SampleProgramTreePlugin extends ProgramPlugin { } @Override - public boolean applyTo(DomainObject obj, TaskMonitor monitor) { - Program program = (Program) obj; + public boolean applyTo(Program program, TaskMonitor monitor) { - listing = program.getListing(); + Listing listing = program.getListing(); createDefaultTreeView(program, programTreeName); @@ -145,8 +141,8 @@ public class SampleProgramTreePlugin extends ProgramPlugin { monitor.setMessage("Module " + start + " : " + mod_name); - ProgramModule mod = make_module(mod_name, frags); - makeFragment(start, end, "frag_" + fragment_count, mod); + ProgramModule mod = make_module(listing, mod_name, frags); + makeFragment(listing, start, end, "frag_" + fragment_count, mod); fragment_count++; } @@ -156,24 +152,17 @@ public class SampleProgramTreePlugin extends ProgramPlugin { private void createDefaultTreeView(Program program, String defaultTreeName) { String treeName = defaultTreeName; int oneUp = 1; + Listing listing = program.getListing(); while (listing.getRootModule(treeName) != null) { treeName = defaultTreeName + "_" + oneUp; oneUp++; } CreateDefaultTreeCmd cmd = new CreateDefaultTreeCmd(defaultTreeName); - if (tool.execute(cmd, program)) { - tool.setStatusInfo(cmd.getStatusMsg()); - } + cmd.applyTo(program); } - /** - * Method make_module. - * @param start - * @param entry_address - * @param prev_name - * @param code - */ - private ProgramModule make_module(String moduleName, ProgramModule parent) { + private ProgramModule make_module(Listing listing, String moduleName, + ProgramModule parent) { String modName = moduleName; int oneUp = 1; @@ -183,6 +172,7 @@ public class SampleProgramTreePlugin extends ProgramPlugin { newMod = parent.createModule(modName); } catch (DuplicateNameException e) { + // ignore } modName = moduleName + "_" + oneUp; oneUp++; @@ -190,19 +180,14 @@ public class SampleProgramTreePlugin extends ProgramPlugin { return newMod; } - /** - * Method make_frag. - * @param start - * @param entry_address - * @param prev_name - */ - private ProgramFragment makeFragment(Address start, Address end, String fragmentName, - ProgramModule parent) { + private ProgramFragment makeFragment(Listing listing, Address start, Address end, + String fragmentName, ProgramModule parent) { try { parent.createFragment(fragmentName); } catch (DuplicateNameException e) { + // ignore } ProgramFragment frag = listing.getFragment(programTreeName, fragmentName); diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/analysis/SharedReturnAnalysisCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/analysis/SharedReturnAnalysisCmd.java index c6fb52a393..ddc805ffc1 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/analysis/SharedReturnAnalysisCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/analysis/SharedReturnAnalysisCmd.java @@ -15,10 +15,12 @@ */ package ghidra.app.cmd.analysis; +import java.util.ArrayList; +import java.util.List; + import ghidra.app.cmd.disassemble.SetFlowOverrideCmd; import ghidra.app.plugin.core.analysis.AutoAnalysisManager; import ghidra.framework.cmd.BackgroundCommand; -import ghidra.framework.model.DomainObject; import ghidra.program.model.address.*; import ghidra.program.model.listing.*; import ghidra.program.model.symbol.*; @@ -26,14 +28,11 @@ import ghidra.util.exception.AssertException; import ghidra.util.exception.CancelledException; import ghidra.util.task.TaskMonitor; -import java.util.ArrayList; -import java.util.List; - /** * Identifies functions to which Jump references exist and converts * the associated branching instruction flow to a CALL-RETURN */ -public class SharedReturnAnalysisCmd extends BackgroundCommand { +public class SharedReturnAnalysisCmd extends BackgroundCommand { private AddressSetView set; private boolean assumeContiguousFunctions = false; @@ -58,9 +57,7 @@ public class SharedReturnAnalysisCmd extends BackgroundCommand { } @Override - public boolean applyTo(DomainObject obj, TaskMonitor monitor) { - - Program program = (Program) obj; + public boolean applyTo(Program program, TaskMonitor monitor) { try { @@ -180,8 +177,8 @@ public class SharedReturnAnalysisCmd extends BackgroundCommand { } // if we have not passed lastFunctionAfter then no change to lastFunctionBefore - if (functionBeforeSrc != null && - (functionAfterSrc == Address.NO_ADDRESS || srcAddr.compareTo(functionAfterSrc) < 0)) { + if (functionBeforeSrc != null && (functionAfterSrc == Address.NO_ADDRESS || + srcAddr.compareTo(functionAfterSrc) < 0)) { // we have not passed lastFunctionAfterSrc - no change to lastFunctionBeforeSrc } else { @@ -276,7 +273,7 @@ public class SharedReturnAnalysisCmd extends BackgroundCommand { } private boolean checkIfCouldHaveFallThruTo(Program program, Address location) { - Instruction instr= program.getListing().getInstructionAt(location); + Instruction instr = program.getListing().getInstructionAt(location); if (instr == null) { return true; } @@ -342,43 +339,43 @@ public class SharedReturnAnalysisCmd extends BackgroundCommand { } - private void checkAllJumpReferences(Program program, TaskMonitor monitor) - throws CancelledException { - - SymbolTable symbolTable = program.getSymbolTable(); - - InstructionIterator instructionIter = program.getListing().getInstructions(set, true); - while (instructionIter.hasNext()) { - monitor.checkCancelled(); - Instruction instr = instructionIter.next(); - FlowType ft = instr.getFlowType(); - if (!ft.isJump()) { - continue; - } - Reference ref = getSingleFlowReferenceFrom(instr); - if (ref == null) { - continue; - } - // if there is a function at this address, this is a thunk - // Handle differently - if (program.getFunctionManager().getFunctionAt(instr.getMinAddress()) != null) { - continue; - } - Symbol s = symbolTable.getPrimarySymbol(ref.getToAddress()); - if (s != null && s.getSymbolType() == SymbolType.FUNCTION) { - if (instr.getFlowOverride() != FlowOverride.NONE) { - continue; - } - SetFlowOverrideCmd cmd = - new SetFlowOverrideCmd(instr.getMinAddress(), FlowOverride.CALL_RETURN); - cmd.applyTo(program); - } - } - } +// private void checkAllJumpReferences(Program program, TaskMonitor monitor) +// throws CancelledException { +// +// SymbolTable symbolTable = program.getSymbolTable(); +// +// InstructionIterator instructionIter = program.getListing().getInstructions(set, true); +// while (instructionIter.hasNext()) { +// monitor.checkCancelled(); +// Instruction instr = instructionIter.next(); +// FlowType ft = instr.getFlowType(); +// if (!ft.isJump()) { +// continue; +// } +// Reference ref = getSingleFlowReferenceFrom(instr); +// if (ref == null) { +// continue; +// } +// // if there is a function at this address, this is a thunk +// // Handle differently +// if (program.getFunctionManager().getFunctionAt(instr.getMinAddress()) != null) { +// continue; +// } +// Symbol s = symbolTable.getPrimarySymbol(ref.getToAddress()); +// if (s != null && s.getSymbolType() == SymbolType.FUNCTION) { +// if (instr.getFlowOverride() != FlowOverride.NONE) { +// continue; +// } +// SetFlowOverrideCmd cmd = +// new SetFlowOverrideCmd(instr.getMinAddress(), FlowOverride.CALL_RETURN); +// cmd.applyTo(program); +// } +// } +// } private void processFunctionJumpReferences(Program program, Address entry, TaskMonitor monitor) throws CancelledException { - + // since reference fixup will occur when flow override is done, // avoid concurrent modification during reference iterator use // by building list of jump references @@ -388,7 +385,7 @@ public class SharedReturnAnalysisCmd extends BackgroundCommand { } FunctionManager funcMgr = program.getFunctionManager(); - + for (Reference ref : fnRefList) { monitor.checkCancelled(); Instruction instr = program.getListing().getInstructionAt(ref.getFromAddress()); @@ -399,15 +396,15 @@ public class SharedReturnAnalysisCmd extends BackgroundCommand { if (checkRef == null) { continue; } - + // if there is a function at this address, this is a thunk // Handle differently Address refInstrAddr = instr.getMinAddress(); - + if (funcMgr.getFunctionAt(refInstrAddr) != null) { continue; } - + // if this instruction is contained in the body of the function // then it is just an internal jump reference to the top of the // function @@ -415,7 +412,7 @@ public class SharedReturnAnalysisCmd extends BackgroundCommand { if (functionContaining != null && functionContaining.getEntryPoint().equals(entry)) { continue; } - + if (checkRef.getToAddress().equals(ref.getToAddress())) { if (instr.getFlowOverride() != FlowOverride.NONE) { continue; diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/comments/AppendCommentCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/comments/AppendCommentCmd.java index 5f1ca5ca1d..4679289592 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/comments/AppendCommentCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/comments/AppendCommentCmd.java @@ -16,14 +16,13 @@ package ghidra.app.cmd.comments; import ghidra.framework.cmd.Command; -import ghidra.framework.model.DomainObject; import ghidra.program.model.address.Address; import ghidra.program.model.listing.*; /** * Command to append a specific type of comment on a code unit. */ -public class AppendCommentCmd implements Command { +public class AppendCommentCmd implements Command { private Address address; private int commentType; @@ -49,24 +48,17 @@ public class AppendCommentCmd implements Command { cmdName = "Append Comment"; } - /** - * @see ghidra.framework.cmd.Command#getName() - */ @Override public String getName() { return cmdName; } - /** - * @see ghidra.framework.cmd.Command#applyTo(ghidra.framework.model.DomainObject) - */ @Override - public boolean applyTo(DomainObject obj) { - CodeUnit cu = getCodeUnit((Program) obj); + public boolean applyTo(Program program) { + CodeUnit cu = getCodeUnit(program); if (cu == null) { - message = - "No Instruction or Data found for address " + address.toString() + - " Is this address valid?"; + message = "No Instruction or Data found for address " + address.toString() + + " Is this address valid?"; return false; } String previousComment = cu.getComment(commentType); @@ -95,9 +87,6 @@ public class AppendCommentCmd implements Command { return cu; } - /** - * @see ghidra.framework.cmd.Command#getStatusMsg() - */ @Override public String getStatusMsg() { return message; diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/comments/CodeUnitInfoPasteCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/comments/CodeUnitInfoPasteCmd.java index 8fb7ab243d..a75d94fbed 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/comments/CodeUnitInfoPasteCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/comments/CodeUnitInfoPasteCmd.java @@ -20,7 +20,6 @@ import java.util.List; import ghidra.app.util.CodeUnitInfo; import ghidra.framework.cmd.Command; -import ghidra.framework.model.DomainObject; import ghidra.program.model.address.Address; import ghidra.program.model.listing.*; import ghidra.program.model.pcode.Varnode; @@ -33,7 +32,7 @@ import ghidra.util.exception.InvalidInputException; * Undoable edit for pasting code unit information at a location. * This class actually does the work of the "paste." */ -public class CodeUnitInfoPasteCmd implements Command { +public class CodeUnitInfoPasteCmd implements Command { // TODO: should refactor to handle all variables in a consistent fashion @@ -48,6 +47,8 @@ public class CodeUnitInfoPasteCmd implements Command { * Creates a new command for pasting comments/labels. * @param startAddr starting address for info * @param infoList list of CodeUnitInfo objects that will be applied + * @param pasteLabels true if labels should be applied, else false + * @param pasteComments true if comments should be applied, else false */ public CodeUnitInfoPasteCmd(Address startAddr, List infoList, boolean pasteLabels, boolean pasteComments) { @@ -65,19 +66,14 @@ public class CodeUnitInfoPasteCmd implements Command { return "Paste Labels/Comments"; } - /* (non-Javadoc) - * @see ghidra.framework.cmd.Command#applyTo(ghidra.framework.model.DomainObject) - */ @Override - public boolean applyTo(DomainObject obj) { + public boolean applyTo(Program program) { - Program program = (Program) obj; SymbolTable symTable = program.getSymbolTable(); Listing listing = program.getListing(); boolean offCutExists = false; - for (int i = 0; i < infoList.size(); i++) { - CodeUnitInfo info = infoList.get(i); + for (CodeUnitInfo info : infoList) { Address a = startAddr.add(info.getIndex()); CodeUnit cu = listing.getCodeUnitAt(a); if (cu == null) { @@ -133,8 +129,8 @@ public class CodeUnitInfoPasteCmd implements Command { function.setName(fnName, info.getPrimarySymbolSource()); } catch (DuplicateNameException e) { - messages.append("Could not set function name--duplicate name: " + fnName).append( - '\n'); + messages.append("Could not set function name--duplicate name: " + fnName) + .append('\n'); } catch (InvalidInputException e) { // shouldn't happen @@ -175,8 +171,8 @@ public class CodeUnitInfoPasteCmd implements Command { } catch (DuplicateNameException e) { messages.append( - "Could not set stack variable name--duplicate name: " + fnName).append( - '\n'); + "Could not set stack variable name--duplicate name: " + fnName) + .append('\n'); } catch (InvalidInputException e) { // shouldn't happen @@ -204,8 +200,8 @@ public class CodeUnitInfoPasteCmd implements Command { var.setName(varNames[i], varSources[i]); } catch (DuplicateNameException e) { - messages.append( - "Could not set variable name--duplicate name: " + fnName).append('\n'); + messages.append("Could not set variable name--duplicate name: " + fnName) + .append('\n'); } catch (InvalidInputException e) { // shouldn't happen @@ -219,8 +215,7 @@ public class CodeUnitInfoPasteCmd implements Command { } private Variable findStackVar(Variable[] stackVars, int stackOffset, int firstUseOffset) { - for (int k = 0; k < stackVars.length; k++) { - Variable var = stackVars[k]; + for (Variable var : stackVars) { if (stackOffset == var.getStackOffset() && firstUseOffset == var.getFirstUseOffset()) { return var; } @@ -229,8 +224,7 @@ public class CodeUnitInfoPasteCmd implements Command { } private Variable findVar(Variable[] vars, Address storageAddr, int firstUseOffset) { - for (int k = 0; k < vars.length; k++) { - Variable var = vars[k]; + for (Variable var : vars) { Varnode varnode = var.getVariableStorage().getFirstVarnode(); if (varnode != null && firstUseOffset == var.getFirstUseOffset() && storageAddr.equals(varnode.getAddress())) { @@ -277,8 +271,8 @@ public class CodeUnitInfoPasteCmd implements Command { } } catch (DuplicateNameException e) { - messages.append("Could not set label name--duplicate name: " + primaryName).append( - '\n'); + messages.append("Could not set label name--duplicate name: " + primaryName) + .append('\n'); } catch (InvalidInputException e) { // should not happen @@ -359,12 +353,12 @@ public class CodeUnitInfoPasteCmd implements Command { private String[] appendComment(String[] comment1, String[] comment2) { // first check for duplicate comments ArrayList list = new ArrayList(); - for (int i = 0; i < comment2.length; i++) { - list.add(comment2[i]); + for (String element : comment2) { + list.add(element); } - for (int i = 0; i < comment1.length; i++) { + for (String element : comment1) { for (int j = 0; j < list.size(); j++) { - if (comment1[i].equals(list.get(j))) { + if (element.equals(list.get(j))) { list.remove(j); --j; } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/comments/SetCommentCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/comments/SetCommentCmd.java index ace2b4a441..d28694d126 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/comments/SetCommentCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/comments/SetCommentCmd.java @@ -17,14 +17,13 @@ package ghidra.app.cmd.comments; import ghidra.app.util.viewer.field.CommentUtils; import ghidra.framework.cmd.Command; -import ghidra.framework.model.DomainObject; import ghidra.program.model.address.Address; import ghidra.program.model.listing.*; /** * Command to set a specific type of comment on a code unit. */ -public class SetCommentCmd implements Command { +public class SetCommentCmd implements Command { private Address address; private int commentType; @@ -67,8 +66,7 @@ public class SetCommentCmd implements Command { } @Override - public boolean applyTo(DomainObject obj) { - Program program = (Program) obj; + public boolean applyTo(Program program) { CodeUnit cu = getCodeUnit(program); if (cu == null) { message = "No Instruction or Data found for address " + address.toString() + diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/comments/SetCommentsCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/comments/SetCommentsCmd.java index 1ea8dd2fc6..cdf7035c72 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/comments/SetCommentsCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/comments/SetCommentsCmd.java @@ -17,14 +17,13 @@ package ghidra.app.cmd.comments; import ghidra.app.util.viewer.field.CommentUtils; import ghidra.framework.cmd.Command; -import ghidra.framework.model.DomainObject; import ghidra.program.model.address.Address; import ghidra.program.model.listing.*; /** * Command for editing and removing comments at an address. */ -public class SetCommentsCmd implements Command { +public class SetCommentsCmd implements Command { private Address address; private String preComment; @@ -79,13 +78,8 @@ public class SetCommentsCmd implements Command { return !oldValue.equals(newValue); } - /** - * - * @see ghidra.framework.cmd.Command#applyTo(ghidra.framework.model.DomainObject) - */ @Override - public boolean applyTo(DomainObject obj) { - Program program = (Program) obj; + public boolean applyTo(Program program) { CodeUnit cu = getCodeUnit(program); if (cu != null) { @@ -138,9 +132,6 @@ public class SetCommentsCmd implements Command { return cu; } - /** - * @see ghidra.framework.cmd.Command#getStatusMsg() - */ @Override public String getStatusMsg() { return msg; diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/data/AbstractCreateStructureCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/data/AbstractCreateStructureCmd.java index 1500f53259..6b9f2e493a 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/data/AbstractCreateStructureCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/data/AbstractCreateStructureCmd.java @@ -16,8 +16,6 @@ package ghidra.app.cmd.data; import ghidra.framework.cmd.Command; -import ghidra.framework.model.DomainObject; - import ghidra.program.model.address.Address; import ghidra.program.model.data.DataType; import ghidra.program.model.data.Structure; @@ -26,128 +24,110 @@ import ghidra.program.model.listing.Program; /** * A base class to hold duplicate information for commands that create * structures. This class implements the logic of the - * {@link #applyTo(DomainObject)} method so that child implementations need + * {@link #applyTo(Program)} method so that child implementations need * only to implement the abstract methods. - * - * - * @since Tracker Id 383 */ -public abstract class AbstractCreateStructureCmd implements Command { - - private String statusMessage; - private String structureName; - private DataType newDataType; - private Address structureAddress; - - /** - * Initializes the this class to create a structure with the given name - * and address when the {@link #applyTo(DomainObject)} is called. - * - * @param name The name of the structure to create. - * @param address The address of the structure. - */ - /*package*/ AbstractCreateStructureCmd( String name, Address address ){ - structureAddress = address; - structureName = name; - } - - /** - * Applies this command to the given domain object. - *

- * This method is a Form Template method in that child subclasses do not - * need to override the method, but only need to implement the methods - * that this method calls. - * - * @param domainObject The domain object that is associated with this - * command - * @see Command#applyTo(DomainObject) - */ - public boolean applyTo(DomainObject domainObject) { - try { - Program program = (Program) domainObject; - Structure structure = createStructure( structureAddress, program ); - setNewDataType( initializeStructureData( program, structure ) ); - } catch (IllegalArgumentException iae) { - setStatusMsg( iae.getMessage() ); - return false; - } - - return true; - } - - /** - * Child classes implement this method in order to create an instance - * of {@link Structure}. - * - * @param address The address of the structure. - * @param program The program of the structure. - * @return A new StructureInfo object that describes the new structure to - * be created. - * @throws IllegalArgumentException If the data at the given address is - * not valid for creating a structure. - */ - /*package*/ abstract Structure createStructure( Address address, - Program program ) - throws IllegalArgumentException; - - /** - * Initializes the structure that is represented by the provided - * structureInfo object. This involves populating the new - * structure with data and then returning the data type object that - * represents the newly created structure. - * - * @param structureInfo The structure info object that describes the newly - * created structure. - * @return The new data type that represents the created structure. - */ - /*package*/ abstract DataType initializeStructureData( - Program program, Structure structure ); - - /** - * Sets the new data type of this command. - * - * @param dataType The new data type. - */ - /*package*/ void setNewDataType( DataType dataType ){ - newDataType = dataType; - } - - /** - * Get the new structure data type which was created. - * @return new structure. - */ - public DataType getNewDataType() { - return newDataType; - } - - /*package*/ Address getStructureAddress(){ - return structureAddress; - } - - /** - * Sets the value of the status message for this command - * - * @param message The value of the command. - */ - /*package*/ void setStatusMsg( String message ){ - statusMessage = message; - } - - /** - * @see ghidra.framework.cmd.Command#getStatusMsg() - */ - public String getStatusMsg(){ - return statusMessage; - } +public abstract class AbstractCreateStructureCmd implements Command { - /*package*/ String getStructureName(){ - return structureName; - } - - /** - * @see ghidra.framework.cmd.Command#getName() - */ - public String getName(){ - return "Create Structure"; - } + private String statusMessage; + private String structureName; + private DataType newDataType; + private Address structureAddress; + + /** + * Initializes the this class to create a structure with the given name + * and address when the {@link #applyTo(Program)} is called. + * + * @param name The name of the structure to create. + * @param address The address of the structure. + */ + /*package*/ AbstractCreateStructureCmd(String name, Address address) { + structureAddress = address; + structureName = name; + } + + @Override + public boolean applyTo(Program program) { + try { + Structure structure = createStructure(structureAddress, program); + setNewDataType(initializeStructureData(program, structure)); + } + catch (IllegalArgumentException iae) { + setStatusMsg(iae.getMessage()); + return false; + } + + return true; + } + + /** + * Child classes implement this method in order to create an instance + * of {@link Structure}. + * + * @param address The address of the structure. + * @param program The program of the structure. + * @return A new StructureInfo object that describes the new structure to + * be created. + * @throws IllegalArgumentException If the data at the given address is + * not valid for creating a structure. + */ + /*package*/ abstract Structure createStructure(Address address, Program program) + throws IllegalArgumentException; + + /** + * Initializes the structure that is represented by the provided + * structureInfo object. This involves populating the new + * structure with data and then returning the data type object that + * represents the newly created structure. + * + * @param program program to be modified + * @param structure The structure definition that describes the newly + * created structure. + * @return The new data type that represents the created structure. + */ + /*package*/ abstract DataType initializeStructureData(Program program, Structure structure); + + /** + * Sets the new data type of this command. + * + * @param dataType The new data type. + */ + /*package*/ void setNewDataType(DataType dataType) { + newDataType = dataType; + } + + /** + * Get the new structure data type which was created. + * @return new structure. + */ + public DataType getNewDataType() { + return newDataType; + } + + /*package*/ Address getStructureAddress() { + return structureAddress; + } + + /** + * Sets the value of the status message for this command + * + * @param message The value of the command. + */ + /*package*/ void setStatusMsg(String message) { + statusMessage = message; + } + + @Override + public String getStatusMsg() { + return statusMessage; + } + + /*package*/ String getStructureName() { + return structureName; + } + + @Override + public String getName() { + return "Create Structure"; + } } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/data/CreateArrayCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/data/CreateArrayCmd.java index c49df702b5..2421de9e08 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/data/CreateArrayCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/data/CreateArrayCmd.java @@ -16,7 +16,6 @@ package ghidra.app.cmd.data; import ghidra.framework.cmd.Command; -import ghidra.framework.model.DomainObject; import ghidra.program.model.address.*; import ghidra.program.model.data.*; import ghidra.program.model.listing.*; @@ -27,7 +26,7 @@ import ghidra.util.Msg; * Command to create an array. All conflicting data will be cleared. * */ -public class CreateArrayCmd implements Command { +public class CreateArrayCmd implements Command { private String msg; private Address addr; private int numElements; @@ -42,7 +41,7 @@ public class CreateArrayCmd implements Command { * @param dt the dataType of the elements in the array to be created. * @param elementLength the size of an element in the array. Only used for Dynamic * datatype dt when {@link Dynamic#canSpecifyLength()} returns true. - */ + */ public CreateArrayCmd(Address addr, int numElements, DataType dt, int elementLength) { this.addr = addr; this.numElements = numElements; @@ -51,8 +50,7 @@ public class CreateArrayCmd implements Command { } @Override - public boolean applyTo(DomainObject obj) { - Program program = (Program)obj; + public boolean applyTo(Program program) { Listing listing = program.getListing(); try { ArrayDataType adt = new ArrayDataType(dataType, numElements, elementLength, @@ -68,7 +66,8 @@ public class CreateArrayCmd implements Command { } listing.clearCodeUnits(addr, endAddr, false); listing.createData(addr, adt, adt.getLength()); - } catch (AddressOverflowException e1) { + } + catch (AddressOverflowException e1) { msg = "Can't create data because length exceeds address space"; return false; } @@ -81,7 +80,7 @@ public class CreateArrayCmd implements Command { Msg.error(this, msg, e); return false; } - return true; + return true; } @Override diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/data/CreateArrayInStructureCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/data/CreateArrayInStructureCmd.java index c80ef3c6c1..9df3e1c40e 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/data/CreateArrayInStructureCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/data/CreateArrayInStructureCmd.java @@ -16,7 +16,6 @@ package ghidra.app.cmd.data; import ghidra.framework.cmd.Command; -import ghidra.framework.model.DomainObject; import ghidra.program.model.address.Address; import ghidra.program.model.data.*; import ghidra.program.model.listing.*; @@ -27,13 +26,13 @@ import ghidra.util.Msg; * within the targeted structure will be replaced with the new array component. * */ -public class CreateArrayInStructureCmd implements Command { +public class CreateArrayInStructureCmd implements Command { private String msg; private Address addr; private int numElements; private DataType dataType; private int[] compPath; - + // NOTE: This command does not currently handle Dynamic types whose length may // be specified since no elementLength parameter exists. @@ -49,9 +48,8 @@ public class CreateArrayInStructureCmd implements Command { * @param compPath the target component path within the structure of an existing component where * the array should be created. The component path is an array of integers where each integer * is a component index of the component above it. - */ - public CreateArrayInStructureCmd(Address addr, int numElements, DataType dt, - int[] compPath) { + */ + public CreateArrayInStructureCmd(Address addr, int numElements, DataType dt, int[] compPath) { this.addr = addr; this.numElements = numElements; this.dataType = dt; @@ -59,8 +57,7 @@ public class CreateArrayInStructureCmd implements Command { } @Override - public boolean applyTo(DomainObject obj) { - Program program = (Program)obj; + public boolean applyTo(Program program) { Listing listing = program.getListing(); Data data = listing.getDataContaining(addr); @@ -70,15 +67,15 @@ public class CreateArrayInStructureCmd implements Command { return false; } - int index = compData.getComponentIndex(); - int offset = compData.getParentOffset(); - DataType parentDataType = compData.getParent().getBaseDataType(); + int index = compData.getComponentIndex(); + int offset = compData.getParentOffset(); + DataType parentDataType = compData.getParent().getBaseDataType(); - if (!(parentDataType instanceof Structure)) { - msg = "Data not in a structure"; - return false; - } - Structure struct = (Structure)parentDataType; + if (!(parentDataType instanceof Structure)) { + msg = "Data not in a structure"; + return false; + } + Structure struct = (Structure) parentDataType; DataType baseDt = dataType; if (dataType instanceof TypeDef) { @@ -90,7 +87,7 @@ public class CreateArrayInStructureCmd implements Command { } try { - ArrayDataType adt = new ArrayDataType(dataType, numElements, dataType.getLength()); + ArrayDataType adt = new ArrayDataType(dataType, numElements, dataType.getLength()); int length = adt.isZeroLength() ? 0 : adt.getLength(); if (!struct.isPackingEnabled() && (offset + length) > struct.getLength()) { msg = "Array too big for structure"; @@ -108,20 +105,20 @@ public class CreateArrayInStructureCmd implements Command { msg = "Unexpected error: " + e.toString(); Msg.error(this, msg, e); return false; - } + } return true; } private void clearStruct(Structure struct, int offset, int length) { DataTypeComponent[] comps = struct.getDefinedComponents(); - int endOffset = offset+length; - for(int i=comps.length-1;i>=0;i--) { + int endOffset = offset + length; + for (int i = comps.length - 1; i >= 0; i--) { if (comps[i].getOffset() >= offset && comps[i].getOffset() < endOffset) { struct.clearComponent(comps[i].getOrdinal()); } } } - + /** * @see ghidra.framework.cmd.Command#getStatusMsg() */ diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/data/CreateDataBackgroundCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/data/CreateDataBackgroundCmd.java index 3fc774b768..d95a5d6125 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/data/CreateDataBackgroundCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/data/CreateDataBackgroundCmd.java @@ -16,7 +16,6 @@ package ghidra.app.cmd.data; import ghidra.framework.cmd.BackgroundCommand; -import ghidra.framework.model.DomainObject; import ghidra.program.model.address.*; import ghidra.program.model.data.DataType; import ghidra.program.model.data.DataUtilities; @@ -37,8 +36,7 @@ import ghidra.util.task.TaskMonitor; * of a pointer, then a pointer to dataType will only be created if there are * enough undefined bytes following to make a pointer. */ -public class CreateDataBackgroundCmd extends BackgroundCommand { - private static final int EVENT_LIMIT = 1000; +public class CreateDataBackgroundCmd extends BackgroundCommand { private AddressSetView addrSet; private DataType newDataType; @@ -76,12 +74,7 @@ public class CreateDataBackgroundCmd extends BackgroundCommand { } @Override - public boolean applyTo(DomainObject obj, TaskMonitor monitor) { - return doApplyTo(obj, monitor); - } - - public boolean doApplyTo(DomainObject obj, TaskMonitor monitor) { - Program program = (Program) obj; + public boolean applyTo(Program program, TaskMonitor monitor) { Listing listing = program.getListing(); InstructionIterator iter = listing.getInstructions(addrSet, true); if (iter.hasNext()) { diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/data/CreateDataCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/data/CreateDataCmd.java index c1cf9aacf4..1cc71e1455 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/data/CreateDataCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/data/CreateDataCmd.java @@ -16,7 +16,6 @@ package ghidra.app.cmd.data; import ghidra.framework.cmd.Command; -import ghidra.framework.model.DomainObject; import ghidra.program.model.address.Address; import ghidra.program.model.data.DataType; import ghidra.program.model.data.DataUtilities; @@ -33,7 +32,7 @@ import ghidra.program.model.listing.Program; * * @see DataUtilities#createData(Program, Address, DataType, int, boolean, DataUtilities.ClearDataMode) */ -public class CreateDataCmd implements Command { +public class CreateDataCmd implements Command { private Address addr; private DataType newDataType; @@ -119,10 +118,9 @@ public class CreateDataCmd implements Command { } @Override - public boolean applyTo(DomainObject obj) { + public boolean applyTo(Program program) { try { - DataUtilities.createData((Program) obj, addr, newDataType, -1, stackPointers, - clearMode); + DataUtilities.createData(program, addr, newDataType, -1, stackPointers, clearMode); return true; } catch (Exception e) { diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/data/CreateDataInStructureBackgroundCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/data/CreateDataInStructureBackgroundCmd.java index 2fe8d40ce3..45ebb94530 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/data/CreateDataInStructureBackgroundCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/data/CreateDataInStructureBackgroundCmd.java @@ -16,7 +16,6 @@ package ghidra.app.cmd.data; import ghidra.framework.cmd.BackgroundCommand; -import ghidra.framework.model.DomainObject; import ghidra.program.model.address.Address; import ghidra.program.model.data.*; import ghidra.program.model.listing.Data; @@ -28,7 +27,7 @@ import ghidra.util.task.TaskMonitor; * Background command to create data across a selection inside of a structure. * */ -public class CreateDataInStructureBackgroundCmd extends BackgroundCommand { +public class CreateDataInStructureBackgroundCmd extends BackgroundCommand { // TODO: Not sure any of this will work for a packed structure which does not support // offset-based component manipulation (see GP-3740) @@ -81,9 +80,8 @@ public class CreateDataInStructureBackgroundCmd extends BackgroundCommand { * @see ghidra.framework.cmd.BackgroundCommand#applyTo(ghidra.framework.model.DomainObject, ghidra.util.task.TaskMonitor) */ @Override - public boolean applyTo(DomainObject obj, TaskMonitor monitor) { + public boolean applyTo(Program program, TaskMonitor monitor) { - Program program = (Program) obj; Data data = program.getListing().getDefinedDataContaining(addr); Data startData = data.getComponent(startPath); if (startData == null) { diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/data/CreateDataInStructureCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/data/CreateDataInStructureCmd.java index adf7a281f8..051c5f9743 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/data/CreateDataInStructureCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/data/CreateDataInStructureCmd.java @@ -16,7 +16,6 @@ package ghidra.app.cmd.data; import ghidra.framework.cmd.Command; -import ghidra.framework.model.DomainObject; import ghidra.program.model.address.Address; import ghidra.program.model.data.*; import ghidra.program.model.listing.Data; @@ -25,7 +24,7 @@ import ghidra.program.model.listing.Program; /** * Command to Create data inside of a structure. */ -public class CreateDataInStructureCmd implements Command { +public class CreateDataInStructureCmd implements Command { // TODO: Not sure any of this will work for a packed structure which does not support // offset-based component manipulation (see GP-3740) @@ -69,12 +68,8 @@ public class CreateDataInStructureCmd implements Command { this.stackPointers = stackPointers; } - /** - * @see ghidra.framework.cmd.Command#applyTo(ghidra.framework.model.DomainObject) - */ @Override - public boolean applyTo(DomainObject obj) { - Program program = (Program) obj; + public boolean applyTo(Program program) { Data data = program.getListing().getDefinedDataContaining(addr); Data dataComp = data.getComponent(componentPath); if (dataComp == null) { @@ -142,17 +137,11 @@ public class CreateDataInStructureCmd implements Command { return true; } - /** - * @see ghidra.framework.cmd.Command#getStatusMsg() - */ @Override public String getStatusMsg() { return msg; } - /** - * @see ghidra.framework.cmd.Command#getName() - */ @Override public String getName() { return "Create " + newDataType.getDisplayName() + " component"; diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/data/CreateStringCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/data/CreateStringCmd.java index 3dd6899db4..bdde2fe417 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/data/CreateStringCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/data/CreateStringCmd.java @@ -16,7 +16,6 @@ package ghidra.app.cmd.data; import ghidra.framework.cmd.Command; -import ghidra.framework.model.DomainObject; import ghidra.program.model.address.Address; import ghidra.program.model.data.*; import ghidra.program.model.data.DataUtilities.ClearDataMode; @@ -27,7 +26,7 @@ import ghidra.program.model.util.CodeUnitInsertionException; * Command to create a String and optionally label it. * */ -public class CreateStringCmd implements Command { +public class CreateStringCmd implements Command { private final Address addr; private final AbstractStringDataType stringDataType; private int length = -1; @@ -39,6 +38,14 @@ public class CreateStringCmd implements Command { : (length > 0) ? new StringDataType() : new TerminatedStringDataType(); } + /** + * Construct command for creating string Data + * @param addr address where string should be created. + * @param stringDataType string datatype + * @param length maximum string length (treatment is specific to specified datatype). + * @param clearMode {@link ClearDataMode} which indicates how existing Data conflicts + * should be handled. + */ public CreateStringCmd(Address addr, AbstractStringDataType stringDataType, int length, ClearDataMode clearMode) { this.addr = addr; @@ -48,41 +55,49 @@ public class CreateStringCmd implements Command { } /** - * Constructs a new command for creating strings. + * Construct command for creating fixed-length ASCII or Unicode string Data + * @param addr address where string should be created. + * @param length byte-length of string + * @param unicode if true Unicode string will be created, else ASCII + * @param clearMode {@link ClearDataMode} which indicates how existing Data conflicts + * should be handled. */ public CreateStringCmd(Address addr, int length, boolean unicode, ClearDataMode clearMode) { this(addr, getStringDataType(unicode, length), length, clearMode); } /** - * Constructs a new command for creating strings. + * Construct command for creating fixed-length ASCII or Unicode string Data. + * Current Data at addr will be cleared if it already exists. + * @param addr address where string should be created. + * @param length byte-length of string + * @param unicode if true Unicode string will be created, else ASCII */ public CreateStringCmd(Address addr, int length, boolean unicode) { this(addr, getStringDataType(unicode, length), length, ClearDataMode.CLEAR_SINGLE_DATA); } /** - * Constructs a new command for creating strings. + * Construct command for creating null-terminated ASCII string Data. + * Current Data at addr will be cleared if it already exists. + * @param addr address where string should be created. */ public CreateStringCmd(Address addr) { this(addr, -1, false); } /** - * Constructs a new command for creating strings. + * Construct command for creating fixed-length ASCII string Data. + * Current Data at addr will be cleared if it already exists. + * @param addr address where string should be created. + * @param length byte-length of string */ public CreateStringCmd(Address addr, int length) { this(addr, length, false); } - /** - * - * @see ghidra.framework.cmd.Command#applyTo(ghidra.framework.model.DomainObject) - */ @Override - public boolean applyTo(DomainObject obj) { - Program program = (Program) obj; - + public boolean applyTo(Program program) { try { DataUtilities.createData(program, addr, stringDataType, length, clearMode); } @@ -94,17 +109,11 @@ public class CreateStringCmd implements Command { return true; } - /** - * @see ghidra.framework.cmd.Command#getStatusMsg() - */ @Override public String getStatusMsg() { return msg; } - /** - * @see ghidra.framework.cmd.Command#getName() - */ @Override public String getName() { return "Create String"; diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/data/CreateStructureCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/data/CreateStructureCmd.java index d414a54e3f..71e210c615 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/data/CreateStructureCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/data/CreateStructureCmd.java @@ -1,6 +1,5 @@ /* ### * IP: GHIDRA - * REVIEWED: YES * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,7 +15,9 @@ */ package ghidra.app.cmd.data; -import ghidra.framework.model.DomainObject; +import java.util.ArrayList; +import java.util.Collections; + import ghidra.program.model.address.*; import ghidra.program.model.data.*; import ghidra.program.model.listing.*; @@ -24,124 +25,120 @@ import ghidra.program.model.symbol.Reference; import ghidra.program.model.symbol.ReferenceManager; import ghidra.program.model.util.CodeUnitInsertionException; -import java.util.ArrayList; - /** * Command to create a structure. */ -public class CreateStructureCmd extends AbstractCreateStructureCmd{ - private int structureDataLength; - private Structure structure; - - /** - * Constructs a new command for creating a new structure and applying it to - * the browser. This method simply calls - * {@link #CreateStructureCmd(String, Address, int)} with - * {@link ghidra.program.model.data.StructureFactory#DEFAULT_STRUCTURE_NAME} as the name of the structure. - * - * @param address the address at which to create the new structure. - * @param length the number of undefined bytes to consume in the new - * structure. - */ - public CreateStructureCmd( Address address, int length ){ - this( StructureFactory.DEFAULT_STRUCTURE_NAME, address, length ); - } - - /** - * Constructs a new command for creating a new structure and applying it to - * the browser. - * @param name The name of the new structure to create. - * @param address the address at which to create the new structure. - * @param length the number of undefined bytes to consume in the new - * structure. - */ - public CreateStructureCmd( String name, Address address, int length ) { - super( name, address ); - structureDataLength = length; - } - - /** - * Creates a new structure by using the provided structure and attaching - * it to the program passed in the {@link #applyTo(DomainObject)} method. - * - * @param newStructure The new structure to attach to the program - * provided in the {@link #applyTo(DomainObject)} method. - * @param address the address at which to create the new structure. - */ - public CreateStructureCmd( Structure newStructure, Address address ){ - super( newStructure.getName(), address ); - structure = newStructure; - structureDataLength = structure.getLength(); - } - - /* - * @see AbstractCreateStructureCmd#createStructure(Address, Program) - */ - @Override - Structure createStructure( Address address, - Program program ){ +public class CreateStructureCmd extends AbstractCreateStructureCmd { + private int structureDataLength; + private Structure structure; - if ( structure == null ){ - structure = - StructureFactory.createStructureDataType( program, address, - structureDataLength, getStructureName(), true ); - } - - return structure; - } - - /* - * @see AbstractCreateStructureCmd#initializeStructureData(Program, Structure) - */ - @Override - DataType initializeStructureData( Program program, Structure localStructure ){ - - Listing listing = program.getListing(); - - Address endAddress; - try { - endAddress = getStructureAddress().addNoWrap(structureDataLength - 1); - } catch (AddressOverflowException e1){ - throw new IllegalArgumentException( - "Can't create structure because length exceeds address " + - "space" + structureDataLength ); - } - ReferenceManager refMgr = program.getReferenceManager(); - Reference[] refs = findExistingRefs( refMgr, program.getAddressFactory(), getStructureAddress(), - endAddress ); - listing.clearCodeUnits( getStructureAddress(), endAddress, false ); - - Data data = null; - try{ - listing.createData(getStructureAddress(), localStructure, - localStructure.getLength()); - refMgr.removeAllReferencesFrom( getStructureAddress(), endAddress ); - addRefs( program, refMgr, refs ); - data = listing.getDataAt( getStructureAddress() ); - } catch(CodeUnitInsertionException e){ - throw new IllegalArgumentException( e.getMessage() ); - } - - return data.getDataType(); - } + /** + * Constructs a new command for creating a new structure and applying it to + * the browser. This method simply calls + * {@link #CreateStructureCmd(String, Address, int)} with + * {@link ghidra.program.model.data.StructureFactory#DEFAULT_STRUCTURE_NAME} as the name of the structure. + * + * @param address the address at which to create the new structure. + * @param length the number of undefined bytes to consume in the new + * structure. + */ + public CreateStructureCmd(Address address, int length) { + this(StructureFactory.DEFAULT_STRUCTURE_NAME, address, length); + } - private Reference[] findExistingRefs(ReferenceManager refMgr, AddressFactory af, Address start, Address end) { - ArrayList list = new ArrayList(); - AddressIterator it = refMgr.getReferenceSourceIterator(new AddressSet(start, end), true); - while(it.hasNext()) { - Address addr = it.next(); - Reference[] refs = refMgr.getReferencesFrom(addr); - for(int i=0;i list = new ArrayList(); + AddressIterator it = refMgr.getReferenceSourceIterator(new AddressSet(start, end), true); + while (it.hasNext()) { + Address addr = it.next(); + Reference[] refs = refMgr.getReferencesFrom(addr); + Collections.addAll(list, refs); + } + Reference[] refList = new Reference[list.size()]; + return list.toArray(refList); + } + + private void addRefs(Program p, ReferenceManager refMgr, Reference[] refs) { + for (Reference ref : refs) { + refMgr.addReference(ref); + } + } } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/data/CreateStructureInStructureCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/data/CreateStructureInStructureCmd.java index 9ba95e5641..9d8dc3a525 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/data/CreateStructureInStructureCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/data/CreateStructureInStructureCmd.java @@ -24,97 +24,93 @@ import ghidra.program.model.listing.Program; * Command to create a structure inside of another structure. * */ -public class CreateStructureInStructureCmd extends AbstractCreateStructureCmd{ +public class CreateStructureInStructureCmd extends AbstractCreateStructureCmd { private int[] fromPath; private int[] toPath; private Structure structure; - - /** - * Constructs a new command for creating structures inside other structures. - * @param address the address of the outer-most structure. - * @param fromPath the componentPath of the first component to be consumed in - * the new structure. - * @param toPath the componentPath of the second component to be consumed in the - * the new structure. - */ - public CreateStructureInStructureCmd( Address address, int[] fromPath, int[] toPath ){ - this( StructureFactory.DEFAULT_STRUCTURE_NAME, address, fromPath, toPath ); - } - + /** * Constructs a new command for creating structures inside other structures. - * - * @param name The name of the structure. + * @param address the address of the outer-most structure. + * @param fromPath the componentPath of the first component to be consumed in + * the new structure. + * @param toPath the componentPath of the second component to be consumed in the + * the new structure. + */ + public CreateStructureInStructureCmd(Address address, int[] fromPath, int[] toPath) { + this(StructureFactory.DEFAULT_STRUCTURE_NAME, address, fromPath, toPath); + } + + /** + * Constructs a new command for creating structures inside other structures. + * + * @param name The name of the structure. * @param addr the address of the outer-most structure. * @param fromPath the componentPath of the first component to be consumed in * the new structure. * @param toPath the componentPath of the second component to be consumed in the * the new structure. */ - public CreateStructureInStructureCmd( String name, Address addr, int[] fromPath, int[] toPath){ - super( name, addr ); + public CreateStructureInStructureCmd(String name, Address addr, int[] fromPath, int[] toPath) { + super(name, addr); this.fromPath = fromPath; this.toPath = toPath; } - public CreateStructureInStructureCmd( Structure newStructure, - Address address, int[] fromPath, int[] toPath ){ - this( address, fromPath, toPath ); - structure = newStructure; - } - - /* - * @see AbstractCreateStructureCmd#createStructure(Address, Program) - */ - /*package*/ @Override - Structure createStructure( Address address, - Program program ){ - - if ( structure == null ){ - structure = StructureFactory.createStructureDataTypeInStrucuture( - program, address, fromPath, toPath, getStructureName(), true ); - } - - return structure; - } - - /* - * @see AbstractCreateStructureCmd#initializeStructureData(StructureInfo) - */ - /*package*/ @Override - DataType initializeStructureData( Program program, Structure localStructure ){ - - Data data = program.getListing().getDataContaining( - getStructureAddress() ); - Data comp1 = data.getComponent( fromPath ); - Data comp2 = data.getComponent(toPath); - int dataLength = (comp2.getParentOffset() + comp2.getLength()) - - comp1.getParentOffset(); - - DataType parentDataType = comp1.getParent().getBaseDataType(); - if ( !(parentDataType instanceof Structure) ){ - throw new IllegalArgumentException( - "Data not in a structure"); - } - Structure originalStructure = (Structure) parentDataType; - - // clear and initialize the original structure and then get the new - // data - clearStruct(originalStructure, comp1.getParentOffset(), dataLength ); - originalStructure.replace(comp1.getComponentIndex(), - localStructure, localStructure.getLength()); - comp1 = data.getComponent( fromPath ); - - return comp1.getDataType(); - } + public CreateStructureInStructureCmd(Structure newStructure, Address address, int[] fromPath, + int[] toPath) { + this(address, fromPath, toPath); + structure = newStructure; + } - private void clearStruct(Structure struct, int offset, int length) { - DataTypeComponent[] comps = struct.getDefinedComponents(); - int endOffset = offset+length; - for(int i=comps.length-1;i>=0;i--) { - if (comps[i].getOffset() >= offset && comps[i].getOffset() < endOffset) { - struct.clearComponent(comps[i].getOrdinal()); - } - } - } + /* + * @see AbstractCreateStructureCmd#createStructure(Address, Program) + */ + /*package*/ @Override + Structure createStructure(Address address, Program program) { + + if (structure == null) { + structure = StructureFactory.createStructureDataTypeInStrucuture(program, address, + fromPath, toPath, getStructureName(), true); + } + + return structure; + } + + /* + * @see AbstractCreateStructureCmd#initializeStructureData(StructureInfo) + */ + /*package*/ @Override + DataType initializeStructureData(Program program, Structure localStructure) { + + Data data = program.getListing().getDataContaining(getStructureAddress()); + Data comp1 = data.getComponent(fromPath); + Data comp2 = data.getComponent(toPath); + int dataLength = (comp2.getParentOffset() + comp2.getLength()) - comp1.getParentOffset(); + + DataType parentDataType = comp1.getParent().getBaseDataType(); + if (!(parentDataType instanceof Structure)) { + throw new IllegalArgumentException("Data not in a structure"); + } + Structure originalStructure = (Structure) parentDataType; + + // clear and initialize the original structure and then get the new + // data + clearStruct(originalStructure, comp1.getParentOffset(), dataLength); + originalStructure.replace(comp1.getComponentIndex(), localStructure, + localStructure.getLength()); + comp1 = data.getComponent(fromPath); + + return comp1.getDataType(); + } + + private void clearStruct(Structure struct, int offset, int length) { + DataTypeComponent[] comps = struct.getDefinedComponents(); + int endOffset = offset + length; + for (int i = comps.length - 1; i >= 0; i--) { + if (comps[i].getOffset() >= offset && comps[i].getOffset() < endOffset) { + struct.clearComponent(comps[i].getOrdinal()); + } + } + } } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/data/RenameDataFieldCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/data/RenameDataFieldCmd.java index b27afe92ca..9c7bdec584 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/data/RenameDataFieldCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/data/RenameDataFieldCmd.java @@ -1,6 +1,5 @@ /* ### * IP: GHIDRA - * REVIEWED: YES * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,22 +16,21 @@ package ghidra.app.cmd.data; import ghidra.framework.cmd.Command; -import ghidra.framework.model.DomainObject; import ghidra.program.model.data.DataTypeComponent; +import ghidra.program.model.listing.Program; import ghidra.util.exception.DuplicateNameException; - /** * Command to rename a component in a data type. * */ -public class RenameDataFieldCmd implements Command { - +public class RenameDataFieldCmd implements Command { + private DataTypeComponent comp; private String newName; private String statusMsg = ""; - + /** * Construct a new RenameDataFieldCmd. * @param comp component in data type to be renamed @@ -43,11 +41,8 @@ public class RenameDataFieldCmd implements Command { this.newName = newName; } - /* - * (non-Javadoc) - * @see ghidra.framework.cmd.Command#applyTo(ghidra.framework.model.DomainObject) - */ - public boolean applyTo(DomainObject obj) { + @Override + public boolean applyTo(Program program) { if (comp == null) { statusMsg = "Null data type"; return false; @@ -55,7 +50,8 @@ public class RenameDataFieldCmd implements Command { try { comp.setFieldName(newName); return true; - } catch(DuplicateNameException e) { + } + catch (DuplicateNameException e) { statusMsg = "Type name already exists: " + newName; } return false; @@ -65,6 +61,7 @@ public class RenameDataFieldCmd implements Command { * (non-Javadoc) * @see ghidra.framework.cmd.Command#getStatusMsg() */ + @Override public String getStatusMsg() { return statusMsg; } @@ -73,6 +70,7 @@ public class RenameDataFieldCmd implements Command { * (non-Javadoc) * @see ghidra.framework.cmd.Command#getName() */ + @Override public String getName() { return "Rename Data Field"; } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/disassemble/ArmDisassembleCommand.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/disassemble/ArmDisassembleCommand.java index 5969c4901a..602c23a736 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/disassemble/ArmDisassembleCommand.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/disassemble/ArmDisassembleCommand.java @@ -15,7 +15,8 @@ */ package ghidra.app.cmd.disassemble; -import ghidra.framework.model.DomainObject; +import java.math.BigInteger; + import ghidra.program.disassemble.DisassemblerContextImpl; import ghidra.program.model.address.*; import ghidra.program.model.lang.Register; @@ -24,8 +25,6 @@ import ghidra.program.model.listing.Program; import ghidra.util.exception.CancelledException; import ghidra.util.task.TaskMonitor; -import java.math.BigInteger; - /** * Command object for performing Arm/Thumb disassembly */ @@ -70,8 +69,7 @@ public class ArmDisassembleCommand extends DisassembleCommand { } @Override - synchronized public boolean applyTo(DomainObject obj, TaskMonitor monitor) { - Program program = (Program) obj; + synchronized public boolean applyTo(Program program, TaskMonitor monitor) { disassemblyPerformed = false; unalignedStart = false; diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/disassemble/DisassembleCommand.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/disassemble/DisassembleCommand.java index 9d5ddddad0..4f02612254 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/disassemble/DisassembleCommand.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/disassemble/DisassembleCommand.java @@ -17,10 +17,10 @@ package ghidra.app.cmd.disassemble; import ghidra.app.plugin.core.analysis.AutoAnalysisManager; import ghidra.framework.cmd.BackgroundCommand; -import ghidra.framework.model.DomainObject; import ghidra.program.disassemble.*; import ghidra.program.model.address.*; -import ghidra.program.model.lang.*; +import ghidra.program.model.lang.Register; +import ghidra.program.model.lang.RegisterValue; import ghidra.program.model.listing.*; import ghidra.program.model.mem.Memory; import ghidra.program.model.mem.MemoryBlock; @@ -30,7 +30,7 @@ import ghidra.util.task.TaskMonitor; /** * Command object for performing disassembly */ -public class DisassembleCommand extends BackgroundCommand { +public class DisassembleCommand extends BackgroundCommand { protected AddressSetView startSet; protected boolean useDefaultRepeatPatternBehavior = false; @@ -78,6 +78,8 @@ public class DisassembleCommand extends BackgroundCommand { * @param startSet set of addresses to be the start of a disassembly. The Command object will * attempt to start a disassembly at each address in this set. * @param restrictedSet addresses that can be disassembled. a null set implies no restrictions + * @param followFlow follow all flows within restricted set if true, otherwise limit to using + * startSet for flows. */ public DisassembleCommand(AddressSetView startSet, AddressSetView restrictedSet, boolean followFlow) { @@ -125,7 +127,7 @@ public class DisassembleCommand extends BackgroundCommand { * Set code analysis enablement. By default new instructions will be submitted for * auto-analysis. * - * @param enable + * @param enable true if incremental code analysis should be done, else false to prevent this. */ public void enableCodeAnalysis(boolean enable) { this.enableAnalysis = enable; @@ -150,8 +152,7 @@ public class DisassembleCommand extends BackgroundCommand { } @Override - synchronized public boolean applyTo(DomainObject obj, TaskMonitor monitor) { - Program program = (Program) obj; + synchronized public boolean applyTo(Program program, TaskMonitor monitor) { return doDisassembly(monitor, program, program.getLanguage().getInstructionAlignment()); } @@ -317,7 +318,7 @@ public class DisassembleCommand extends BackgroundCommand { * * @param disassembler disassembler to use * @param seedSet set of addresses to be disassembled - * @param mgr + * @param mgr auto analysis manager * * @return addresses actually disassembled */ diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/disassemble/Hcs12DisassembleCommand.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/disassemble/Hcs12DisassembleCommand.java index 6dff9cd0c8..7e9e096913 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/disassemble/Hcs12DisassembleCommand.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/disassemble/Hcs12DisassembleCommand.java @@ -17,7 +17,6 @@ package ghidra.app.cmd.disassemble; import java.math.BigInteger; -import ghidra.framework.model.DomainObject; import ghidra.program.disassemble.DisassemblerContextImpl; import ghidra.program.model.address.*; import ghidra.program.model.lang.Register; @@ -70,8 +69,7 @@ public class Hcs12DisassembleCommand extends DisassembleCommand { } @Override - synchronized public boolean applyTo(DomainObject obj, TaskMonitor monitor) { - Program program = (Program) obj; + synchronized public boolean applyTo(Program program, TaskMonitor monitor) { disassemblyPerformed = false; unalignedStart = false; diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/disassemble/MipsDisassembleCommand.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/disassemble/MipsDisassembleCommand.java index 1dd0740d70..52bc259404 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/disassemble/MipsDisassembleCommand.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/disassemble/MipsDisassembleCommand.java @@ -17,7 +17,6 @@ package ghidra.app.cmd.disassemble; import java.math.BigInteger; -import ghidra.framework.model.DomainObject; import ghidra.program.disassemble.DisassemblerContextImpl; import ghidra.program.model.address.*; import ghidra.program.model.lang.Register; @@ -75,8 +74,7 @@ public class MipsDisassembleCommand extends DisassembleCommand { } @Override - synchronized public boolean applyTo(DomainObject obj, TaskMonitor monitor) { - Program program = (Program) obj; + synchronized public boolean applyTo(Program program, TaskMonitor monitor) { disassemblyPerformed = false; unalignedStart = false; @@ -90,7 +88,7 @@ public class MipsDisassembleCommand extends DisassembleCommand { setStatusMsg("MIPS16 mode not supported"); return false; } - return super.applyTo(obj, monitor); + return super.applyTo(program, monitor); } RegisterValue m16modeValue = diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/disassemble/PowerPCDisassembleCommand.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/disassemble/PowerPCDisassembleCommand.java index f36aec3509..b72dc41160 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/disassemble/PowerPCDisassembleCommand.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/disassemble/PowerPCDisassembleCommand.java @@ -17,7 +17,6 @@ package ghidra.app.cmd.disassemble; import java.math.BigInteger; -import ghidra.framework.model.DomainObject; import ghidra.program.disassemble.DisassemblerContextImpl; import ghidra.program.model.address.*; import ghidra.program.model.lang.Register; @@ -77,8 +76,7 @@ public class PowerPCDisassembleCommand extends DisassembleCommand { } @Override - synchronized public boolean applyTo(DomainObject obj, TaskMonitor monitor) { - Program program = (Program) obj; + synchronized public boolean applyTo(Program program, TaskMonitor monitor) { disassemblyPerformed = false; unalignedStart = false; @@ -92,7 +90,7 @@ public class PowerPCDisassembleCommand extends DisassembleCommand { setStatusMsg("PowerISA VLE mode not supported"); return false; } - return super.applyTo(obj, monitor); + return super.applyTo(program, monitor); } RegisterValue vlemodeValue = diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/disassemble/ReDisassembleCommand.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/disassemble/ReDisassembleCommand.java index 1e7f347efb..bc0de5e8f7 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/disassemble/ReDisassembleCommand.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/disassemble/ReDisassembleCommand.java @@ -16,14 +16,13 @@ package ghidra.app.cmd.disassemble; import ghidra.framework.cmd.BackgroundCommand; -import ghidra.framework.model.DomainObject; import ghidra.program.disassemble.ReDisassembler; import ghidra.program.model.address.Address; import ghidra.program.model.listing.Program; import ghidra.util.exception.CancelledException; import ghidra.util.task.TaskMonitor; -public class ReDisassembleCommand extends BackgroundCommand { +public class ReDisassembleCommand extends BackgroundCommand { private final Address seed; public ReDisassembleCommand(Address seed) { @@ -31,8 +30,8 @@ public class ReDisassembleCommand extends BackgroundCommand { } @Override - public boolean applyTo(DomainObject obj, TaskMonitor monitor) { - ReDisassembler dis = new ReDisassembler((Program) obj); + public boolean applyTo(Program program, TaskMonitor monitor) { + ReDisassembler dis = new ReDisassembler(program); try { dis.disasemble(seed, monitor); return true; diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/disassemble/SetFlowOverrideCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/disassemble/SetFlowOverrideCmd.java index fd59b127ad..4384c8d6c4 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/disassemble/SetFlowOverrideCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/disassemble/SetFlowOverrideCmd.java @@ -1,6 +1,5 @@ /* ### * IP: GHIDRA - * REVIEWED: YES * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,7 +16,6 @@ package ghidra.app.cmd.disassemble; import ghidra.framework.cmd.BackgroundCommand; -import ghidra.framework.model.DomainObject; import ghidra.program.model.address.Address; import ghidra.program.model.address.AddressSetView; import ghidra.program.model.listing.*; @@ -26,7 +24,7 @@ import ghidra.util.task.TaskMonitor; /** * Command for setting the fallthrough property on an instruction. */ -public class SetFlowOverrideCmd extends BackgroundCommand { +public class SetFlowOverrideCmd extends BackgroundCommand { Address instAddr; AddressSetView set; FlowOverride flowOverride; @@ -60,9 +58,7 @@ public class SetFlowOverrideCmd extends BackgroundCommand { } @Override - public boolean applyTo(DomainObject obj, TaskMonitor monitor) { - - Program program = (Program) obj; + public boolean applyTo(Program program, TaskMonitor monitor) { if (set != null) { int cnt = 0; diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/disassemble/X86_64DisassembleCommand.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/disassemble/X86_64DisassembleCommand.java index 9037dfbe6e..f06f1ead1a 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/disassemble/X86_64DisassembleCommand.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/disassemble/X86_64DisassembleCommand.java @@ -19,10 +19,10 @@ import java.math.BigInteger; import javax.help.UnsupportedOperationException; -import ghidra.framework.model.DomainObject; import ghidra.program.disassemble.DisassemblerContextImpl; import ghidra.program.model.address.*; -import ghidra.program.model.lang.*; +import ghidra.program.model.lang.Register; +import ghidra.program.model.lang.RegisterValue; import ghidra.program.model.listing.Program; import ghidra.program.model.listing.ProgramContext; import ghidra.util.exception.CancelledException; @@ -91,8 +91,7 @@ public class X86_64DisassembleCommand extends DisassembleCommand { throw new UnsupportedOperationException(); } - public static AddressSet alignSet(int alignment, AddressSetView set) - throws CancelledException { + public static AddressSet alignSet(int alignment, AddressSetView set) { AddressSet result = new AddressSet(); for (AddressRange range : set) { Address min = range.getMinAddress(); @@ -115,8 +114,7 @@ public class X86_64DisassembleCommand extends DisassembleCommand { } @Override - synchronized public boolean applyTo(DomainObject obj, TaskMonitor monitor) { - Program program = (Program) obj; + synchronized public boolean applyTo(Program program, TaskMonitor monitor) { disassemblyPerformed = false; unalignedStart = false; @@ -130,8 +128,8 @@ public class X86_64DisassembleCommand extends DisassembleCommand { languageError = "Requires x86:LE:64:default"; return false; } - RegisterValue ctx = new RegisterValue(context.getBaseContextRegister()) - .assign(longModeReg, size32Mode ? BigInteger.ZERO : BigInteger.ONE); + RegisterValue ctx = new RegisterValue(context.getBaseContextRegister()).assign(longModeReg, + size32Mode ? BigInteger.ZERO : BigInteger.ONE); super.setInitialContext(ctx); diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/equate/ClearEquateCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/equate/ClearEquateCmd.java index 852e828e69..17ce0b6fcb 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/equate/ClearEquateCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/equate/ClearEquateCmd.java @@ -16,13 +16,12 @@ package ghidra.app.cmd.equate; import ghidra.framework.cmd.Command; -import ghidra.framework.model.DomainObject; import ghidra.program.model.address.Address; import ghidra.program.model.listing.Program; import ghidra.program.model.symbol.Equate; import ghidra.program.model.symbol.EquateTable; -public class ClearEquateCmd implements Command { +public class ClearEquateCmd implements Command { private String equateName; private Address addr; @@ -42,8 +41,8 @@ public class ClearEquateCmd implements Command { } @Override - public boolean applyTo(DomainObject obj) { - EquateTable equateTable = ((Program) obj).getEquateTable(); + public boolean applyTo(Program program) { + EquateTable equateTable = program.getEquateTable(); Equate equate = equateTable.getEquate(equateName); clearEquate(equate, equateTable); diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/equate/SetEquateCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/equate/SetEquateCmd.java index 5164e6784b..d07148c3f9 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/equate/SetEquateCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/equate/SetEquateCmd.java @@ -16,7 +16,6 @@ package ghidra.app.cmd.equate; import ghidra.framework.cmd.Command; -import ghidra.framework.model.DomainObject; import ghidra.program.model.address.Address; import ghidra.program.model.listing.Program; import ghidra.program.model.symbol.Equate; @@ -27,7 +26,7 @@ import ghidra.util.exception.InvalidInputException; /** * Command for setting an equate at a location. */ -public class SetEquateCmd implements Command { +public class SetEquateCmd implements Command { private String equateName; private Address addr; @@ -52,24 +51,19 @@ public class SetEquateCmd implements Command { this.equateValue = equateValue; } - /** - * The name of the edit action. - */ @Override public String getName() { return "Set Equate"; } @Override - public boolean applyTo(DomainObject obj) { - EquateTable equateTable = ((Program) obj).getEquateTable(); + public boolean applyTo(Program program) { + EquateTable equateTable = program.getEquateTable(); equate = equateTable.getEquate(equateName); - if (existsWithDifferentValue(equate)) { - msg = - "Equate named " + equateName + " already exists with value of " + - equate.getValue() + "."; + msg = "Equate named " + equateName + " already exists with value of " + + equate.getValue() + "."; return false; } @@ -101,9 +95,6 @@ public class SetEquateCmd implements Command { return equate; } - /** - * @see ghidra.framework.cmd.Command#getStatusMsg() - */ @Override public String getStatusMsg() { return msg; diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/AddFunctionTagCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/AddFunctionTagCmd.java index da8dc86e4c..15be1d4012 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/AddFunctionTagCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/AddFunctionTagCmd.java @@ -16,17 +16,14 @@ package ghidra.app.cmd.function; import ghidra.framework.cmd.Command; -import ghidra.framework.model.DomainObject; -import ghidra.program.database.ProgramDB; import ghidra.program.model.address.Address; -import ghidra.program.model.listing.Function; -import ghidra.program.model.listing.FunctionManager; +import ghidra.program.model.listing.*; /** * Command for assigning a tag to a function. Executing this will pop up a dialog * allowing the user to assign tags to a function. */ -public class AddFunctionTagCmd implements Command { +public class AddFunctionTagCmd implements Command { private Address entryPoint; private String tagName; @@ -44,8 +41,7 @@ public class AddFunctionTagCmd implements Command { } @Override - public boolean applyTo(DomainObject obj) { - ProgramDB program = (ProgramDB) obj; + public boolean applyTo(Program program) { FunctionManager functionManager = program.getFunctionManager(); Function function = functionManager.getFunctionAt(entryPoint); diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/AddMemoryParameterCommand.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/AddMemoryParameterCommand.java index a4fce075e9..fddac3e84e 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/AddMemoryParameterCommand.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/AddMemoryParameterCommand.java @@ -1,6 +1,5 @@ /* ### * IP: GHIDRA - * REVIEWED: YES * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,12 +23,16 @@ import ghidra.util.exception.InvalidInputException; /** * A command to create a new function memory parameter. + * + * @deprecated function signatures should be modified in their entirety using + * either {@link UpdateFunctionCommand} or {@link ApplyFunctionSignatureCmd}. */ +@Deprecated(since = "11.1") public class AddMemoryParameterCommand extends AddParameterCommand { - private Address memAddr; - private String name; - private DataType dataType; + private final Address memAddr; + private final String name; + private final DataType dataType; public AddMemoryParameterCommand(Function function, Address memAddr, String name, DataType dataType, int ordinal, SourceType source) { @@ -37,7 +40,6 @@ public class AddMemoryParameterCommand extends AddParameterCommand { this.memAddr = memAddr; this.name = name; this.dataType = dataType; - this.ordinal = ordinal; } @Override @@ -45,9 +47,6 @@ public class AddMemoryParameterCommand extends AddParameterCommand { return new ParameterImpl(name, dataType, memAddr, program); } - /** - * @see ghidra.framework.cmd.Command#getName() - */ @Override public String getName() { return "Create Memory Parameter"; diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/AddMemoryVarCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/AddMemoryVarCmd.java index fa6281b669..4dc41ad0d8 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/AddMemoryVarCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/AddMemoryVarCmd.java @@ -1,6 +1,5 @@ /* ### * IP: GHIDRA - * REVIEWED: YES * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,7 +16,6 @@ package ghidra.app.cmd.function; import ghidra.framework.cmd.Command; -import ghidra.framework.model.DomainObject; import ghidra.program.model.address.Address; import ghidra.program.model.data.DataType; import ghidra.program.model.listing.*; @@ -28,8 +26,8 @@ import ghidra.util.exception.InvalidInputException; /** * Command to add a memory variable to a function. */ -public class AddMemoryVarCmd implements Command { - private Program program; +public class AddMemoryVarCmd implements Command { + private Address memAddr; private Address firstUseAddr; private String name; @@ -68,13 +66,8 @@ public class AddMemoryVarCmd implements Command { this.source = source; } - /** - * - * @see ghidra.framework.cmd.Command#applyTo(ghidra.framework.model.DomainObject) - */ @Override - public boolean applyTo(DomainObject obj) { - program = (Program) obj; + public boolean applyTo(Program program) { Function f = program.getListing().getFunctionContaining(firstUseAddr); if (f == null) { @@ -100,17 +93,11 @@ public class AddMemoryVarCmd implements Command { return true; } - /** - * @see ghidra.framework.cmd.Command#getName() - */ @Override public String getName() { return "Create Memory Variable"; } - /** - * @see ghidra.framework.cmd.Command#getStatusMsg() - */ @Override public String getStatusMsg() { return errMsg; diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/AddParameterCommand.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/AddParameterCommand.java index c431d6a71c..0b3c01c549 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/AddParameterCommand.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/AddParameterCommand.java @@ -1,6 +1,5 @@ /* ### * IP: GHIDRA - * REVIEWED: YES * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,7 +16,6 @@ package ghidra.app.cmd.function; import ghidra.framework.cmd.Command; -import ghidra.framework.model.DomainObject; import ghidra.program.model.listing.*; import ghidra.program.model.symbol.SourceType; import ghidra.util.exception.DuplicateNameException; @@ -29,17 +27,23 @@ import ghidra.util.exception.InvalidInputException; * Note: If no ordinal is provided to this class at construction time, then * the ordinal of hte given parameter will be used. * + * @see AddRegisterParameterCommand + * @see AddStackParameterCommand + * @see AddMemoryParameterCommand * - * @see ghidra.app.cmd.function.AddRegisterParameterCommand - * @see ghidra.app.cmd.function.AddStackParameterCommand + * @deprecated function signatures should be modified in their entirety using + * either {@link UpdateFunctionCommand} or {@link ApplyFunctionSignatureCmd}. */ -public class AddParameterCommand implements Command { +@Deprecated(since = "11.1") +public class AddParameterCommand implements Command { + + protected final Function function; + protected final int ordinal; + protected final SourceType source; + + private final Parameter parameter; - protected Function function; - protected Parameter parameter; protected String statusMessage; - protected int ordinal; - protected SourceType source; public AddParameterCommand(Function function, Parameter parameter, int ordinal, SourceType source) { @@ -49,31 +53,32 @@ public class AddParameterCommand implements Command { this.source = source; } -// // lets this be usable by code that already has a parameter -// public AddParameterCommand(Function function, Parameter parameter) { -// this(function, parameter, parameter.getOrdinal()); -// } - // allows subclasses to use this class without having to already have // a parameter created protected AddParameterCommand(Function function, int ordinal, SourceType source) { this(function, null, ordinal, source); } + /** + * Get parameter to be added + * @param program target program + * @return parameter to be added + * @throws InvalidInputException if unable to generate parameter due to invalid data + */ protected Parameter getParameter(Program program) throws InvalidInputException { return parameter; } - /** - * @see ghidra.framework.cmd.Command#applyTo(ghidra.framework.model.DomainObject) - */ @Override - public boolean applyTo(DomainObject obj) { + public final boolean applyTo(Program program) { + if (program != function.getProgram()) { + throw new AssertionError("Program instance mismatch"); + } String name = null; try { - Parameter parameter2add = getParameter((Program) obj); - name = parameter2add.getName(); - if (function.insertParameter(ordinal, parameter2add, source) == null) { + Parameter param = getParameter(program); + name = param.getName(); + if (function.insertParameter(ordinal, param, source) == null) { statusMessage = "Create parameter failed"; return false; } @@ -102,17 +107,11 @@ public class AddParameterCommand implements Command { return true; } - /** - * @see ghidra.framework.cmd.Command#getStatusMsg() - */ @Override public String getStatusMsg() { return statusMessage; } - /** - * @see ghidra.framework.cmd.Command#getName() - */ @Override public String getName() { return "Add Parameter Command"; diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/AddRegisterParameterCommand.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/AddRegisterParameterCommand.java index 59199f1567..8944a82371 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/AddRegisterParameterCommand.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/AddRegisterParameterCommand.java @@ -1,6 +1,5 @@ /* ### * IP: GHIDRA - * REVIEWED: YES * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,14 +24,15 @@ import ghidra.util.exception.InvalidInputException; /** * A command to create a new function register parameter. * - * - * @since Tracker Id 526 + * @deprecated function signatures should be modified in their entirety using + * either {@link UpdateFunctionCommand} or {@link ApplyFunctionSignatureCmd}. */ +@Deprecated(since = "11.1") public class AddRegisterParameterCommand extends AddParameterCommand { - private Register register; - private String name; - private DataType dataType; + private final Register register; + private final String name; + private final DataType dataType; public AddRegisterParameterCommand(Function function, Register register, String name, DataType dataType, int ordinal, SourceType source) { @@ -40,7 +40,6 @@ public class AddRegisterParameterCommand extends AddParameterCommand { this.register = register; this.name = name; this.dataType = dataType; - this.ordinal = ordinal; } @Override @@ -48,9 +47,6 @@ public class AddRegisterParameterCommand extends AddParameterCommand { return new ParameterImpl(name, dataType, register, program); } - /** - * @see ghidra.framework.cmd.Command#getName() - */ @Override public String getName() { return "Create Register Parameter"; diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/AddRegisterVarCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/AddRegisterVarCmd.java index a94e24d17b..fc2410e53d 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/AddRegisterVarCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/AddRegisterVarCmd.java @@ -1,6 +1,5 @@ /* ### * IP: GHIDRA - * REVIEWED: YES * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,7 +16,6 @@ package ghidra.app.cmd.function; import ghidra.framework.cmd.Command; -import ghidra.framework.model.DomainObject; import ghidra.program.model.address.Address; import ghidra.program.model.data.DataType; import ghidra.program.model.lang.Register; @@ -30,9 +28,8 @@ import ghidra.util.exception.InvalidInputException; * Command to add a register variable to a function. * */ -public class AddRegisterVarCmd implements Command { +public class AddRegisterVarCmd implements Command { - private Program program; private Address addr; private Register reg; private String name; @@ -71,13 +68,8 @@ public class AddRegisterVarCmd implements Command { this.source = source; } - /** - * - * @see ghidra.framework.cmd.Command#applyTo(ghidra.framework.model.DomainObject) - */ @Override - public boolean applyTo(DomainObject obj) { - program = (Program) obj; + public boolean applyTo(Program program) { Function f = program.getListing().getFunctionContaining(addr); if (f == null) { diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/AddStackParameterCommand.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/AddStackParameterCommand.java index 37d8eaef92..8cc382d135 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/AddStackParameterCommand.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/AddStackParameterCommand.java @@ -1,6 +1,5 @@ /* ### * IP: GHIDRA - * REVIEWED: YES * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,14 +23,15 @@ import ghidra.util.exception.InvalidInputException; /** * A command to create a new function stack parameter. * - * - * @since Tracker Id 526 + * @deprecated function signatures should be modified in their entirety using + * either {@link UpdateFunctionCommand} or {@link ApplyFunctionSignatureCmd}. */ +@Deprecated(since = "11.1") public class AddStackParameterCommand extends AddParameterCommand { - private int stackOffset; - private String name; - private DataType dataType; + private final int stackOffset; + private final String name; + private final DataType dataType; public AddStackParameterCommand(Function function, int stackOffset, String name, DataType dataType, int ordinal, SourceType source) { @@ -39,8 +39,6 @@ public class AddStackParameterCommand extends AddParameterCommand { this.stackOffset = stackOffset; this.name = name; this.dataType = dataType; - this.ordinal = ordinal; - this.source = source; } @Override diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/AddStackVarCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/AddStackVarCmd.java index 5d182b949d..54b4ba1ebe 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/AddStackVarCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/AddStackVarCmd.java @@ -1,6 +1,5 @@ /* ### * IP: GHIDRA - * REVIEWED: YES * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,7 +16,6 @@ package ghidra.app.cmd.function; import ghidra.framework.cmd.Command; -import ghidra.framework.model.DomainObject; import ghidra.program.model.address.Address; import ghidra.program.model.data.DataType; import ghidra.program.model.listing.*; @@ -28,8 +26,8 @@ import ghidra.util.exception.InvalidInputException; /** * Command to add a stack variable to a function. */ -public class AddStackVarCmd implements Command { - private Program program; +public class AddStackVarCmd implements Command { + private Address addr; private int stackOffset; private String name; @@ -37,7 +35,6 @@ public class AddStackVarCmd implements Command { private SourceType source; private String errMsg = ""; - /** * Constructs a new command to add a stack variable to a function. * @param addr initial declaration point of variable. @@ -46,26 +43,23 @@ public class AddStackVarCmd implements Command { * @param dataType variable data-type or null for a default data type of minimal size * @param source the source of this stack variable */ - public AddStackVarCmd(Address addr, int stackOffset, String name, DataType dataType, SourceType source) { - this.addr = addr; - this.stackOffset = stackOffset; - this.name = name; - this.dataType = dataType; - this.source = source; - } + public AddStackVarCmd(Address addr, int stackOffset, String name, DataType dataType, + SourceType source) { + this.addr = addr; + this.stackOffset = stackOffset; + this.name = name; + this.dataType = dataType; + this.source = source; + } - /** - * - * @see ghidra.framework.cmd.Command#applyTo(ghidra.framework.model.DomainObject) - */ - public boolean applyTo(DomainObject obj) { - program = (Program)obj; - if (dataType != null) { - dataType = dataType.clone(program.getDataTypeManager()); - } + @Override + public boolean applyTo(Program program) { + if (dataType != null) { + dataType = dataType.clone(program.getDataTypeManager()); + } Function f = program.getListing().getFunctionContaining(addr); if (f == null) { - errMsg="Address not contained within function: " +addr; + errMsg = "Address not contained within function: " + addr; return false; } StackFrame sf = f.getStackFrame(); @@ -77,27 +71,25 @@ public class AddStackVarCmd implements Command { errMsg = "Create stack variable failed"; return false; } - } catch (DuplicateNameException e) { + } + catch (DuplicateNameException e) { errMsg = "Variable named " + name + " already exists"; return false; - } catch (InvalidInputException e) { + } + catch (InvalidInputException e) { errMsg = e.getMessage(); return false; } return true; - } + } - /** - * @see ghidra.framework.cmd.Command#getName() - */ - public String getName() { - return "Create Stack Variable"; - } + @Override + public String getName() { + return "Create Stack Variable"; + } - /** - * @see ghidra.framework.cmd.Command#getStatusMsg() - */ - public String getStatusMsg() { - return errMsg; - } + @Override + public String getStatusMsg() { + return errMsg; + } } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/ApplyFunctionDataTypesCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/ApplyFunctionDataTypesCmd.java index a18c7a9acb..caf00f7711 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/ApplyFunctionDataTypesCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/ApplyFunctionDataTypesCmd.java @@ -20,7 +20,6 @@ import java.util.*; import ghidra.app.cmd.disassemble.DisassembleCommand; import ghidra.app.util.PseudoDisassembler; import ghidra.framework.cmd.BackgroundCommand; -import ghidra.framework.model.DomainObject; import ghidra.program.model.address.Address; import ghidra.program.model.address.AddressSetView; import ghidra.program.model.data.*; @@ -36,7 +35,7 @@ import ghidra.util.task.TaskMonitor; * any user defined label that has the same name as the function * signature. */ -public class ApplyFunctionDataTypesCmd extends BackgroundCommand { +public class ApplyFunctionDataTypesCmd extends BackgroundCommand { private Program program; private BookmarkManager bookmarkMgr; private List sourceCategories; @@ -83,8 +82,8 @@ public class ApplyFunctionDataTypesCmd extends BackgroundCommand { * @param createBookmarksEnabled true to create a bookmark when a function signature * has been applied. */ - public ApplyFunctionDataTypesCmd(Category sourceCategory, AddressSetView set, - SourceType source, boolean alwaysReplace, boolean createBookmarksEnabled) { + public ApplyFunctionDataTypesCmd(Category sourceCategory, AddressSetView set, SourceType source, + boolean alwaysReplace, boolean createBookmarksEnabled) { super("Apply Function Data Types", true, false, false); this.sourceCategories = List.of(sourceCategory); this.addresses = set; @@ -102,8 +101,8 @@ public class ApplyFunctionDataTypesCmd extends BackgroundCommand { } @Override - public boolean applyTo(DomainObject obj, TaskMonitor monitor) { - program = (Program) obj; + public boolean applyTo(Program p, TaskMonitor monitor) { + program = p; bookmarkMgr = program.getBookmarkManager(); monitor.setMessage("Applying Function Signatures"); @@ -179,8 +178,8 @@ public class ApplyFunctionDataTypesCmd extends BackgroundCommand { * @param symbolMap symbol map where possible function definitions may be applied * @throws CancelledException if task cancelled */ - private void applyFunctionDefinitions(TaskMonitor monitor, - Map> symbolMap) throws CancelledException { + private void applyFunctionDefinitions(TaskMonitor monitor, Map> symbolMap) + throws CancelledException { Map functionNameMap = new HashMap<>(); for (Category cat : sourceCategories) { @@ -321,7 +320,7 @@ public class ApplyFunctionDataTypesCmd extends BackgroundCommand { if (instrBefore != null && address.equals(instrBefore.getFallThrough())) { return false; } - + // check if part of a larger code-block ReferenceIterator referencesTo = program.getReferenceManager().getReferencesTo(address); for (Reference reference : referencesTo) { @@ -399,7 +398,7 @@ public class ApplyFunctionDataTypesCmd extends BackgroundCommand { * * @param symbolMap map of symbol names to all matching symbols * @param prefix optional prefix on symbol to lookup - * @param fdef function definition + * @param functionName function name * @return symbol definition; null if no symbol is found for the given name */ private List lookupSymbol(Map> symbolMap, String prefix, diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/ApplyFunctionSignatureCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/ApplyFunctionSignatureCmd.java index 6150b8db97..bb2f990d9a 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/ApplyFunctionSignatureCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/ApplyFunctionSignatureCmd.java @@ -19,7 +19,6 @@ import java.util.ArrayList; import java.util.List; import ghidra.framework.cmd.BackgroundCommand; -import ghidra.framework.model.DomainObject; import ghidra.program.model.address.Address; import ghidra.program.model.data.*; import ghidra.program.model.lang.CompilerSpec; @@ -37,9 +36,11 @@ import ghidra.util.task.TaskMonitor; /** * Command to create apply a function signature at an address. * - * + * {@link Function} signature changes are applied using + * {@link Function#updateFunction(String, Variable, List, FunctionUpdateType, boolean, SourceType)} + * with an update type of {@link FunctionUpdateType#DYNAMIC_STORAGE_FORMAL_PARAMS}. */ -public class ApplyFunctionSignatureCmd extends BackgroundCommand { +public class ApplyFunctionSignatureCmd extends BackgroundCommand { private Address entryPt; private SourceType source; private FunctionRenameOption functionRenameOption; @@ -159,8 +160,8 @@ public class ApplyFunctionSignatureCmd extends BackgroundCommand { } @Override - public boolean applyTo(DomainObject obj, TaskMonitor monitor) { - program = (Program) obj; + public boolean applyTo(Program p, TaskMonitor monitor) { + this.program = p; Function func = program.getListing().getFunctionContaining(entryPt); diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/CallDepthChangeInfo.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/CallDepthChangeInfo.java index 87496fde42..df9c15ee7c 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/CallDepthChangeInfo.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/CallDepthChangeInfo.java @@ -15,16 +15,17 @@ */ package ghidra.app.cmd.function; -import java.util.*; +import java.util.ArrayList; +import java.util.HashMap; import ghidra.program.model.address.*; import ghidra.program.model.block.CodeBlock; -import ghidra.program.model.lang.*; +import ghidra.program.model.lang.ProcessorContext; +import ghidra.program.model.lang.Register; import ghidra.program.model.listing.*; import ghidra.program.model.pcode.*; import ghidra.program.model.scalar.Scalar; import ghidra.program.model.symbol.FlowType; -import ghidra.program.model.symbol.Reference; import ghidra.program.model.util.*; import ghidra.program.util.*; import ghidra.program.util.SymbolicPropogator.Value; @@ -33,13 +34,6 @@ import ghidra.util.exception.*; import ghidra.util.task.TaskMonitor; /** - * CallDepthChangeInfo.java - * - * Date: Feb 6, 2003 - * - */ -/** - * * Given a function in a program or the start of a function, record information * about the change to a stack pointer from a subroutine call. The routine * getCallChange() can be called with the address of a call instruction. If the @@ -49,10 +43,7 @@ import ghidra.util.task.TaskMonitor; * The computation is based on a set of equations that are generated and solved. * Each equation represents the stack change for a given basic flow block or * call instruction within the function. - * - * */ - public class CallDepthChangeInfo { Program program; @@ -142,17 +133,10 @@ public class CallDepthChangeInfo { public CallDepthChangeInfo(Program program, Address addr, AddressSetView restrictSet, Register frameReg, TaskMonitor monitor) throws CancelledException { Function func = program.getFunctionManager().getFunctionContaining(addr); - Register stackReg = program.getCompilerSpec().getStackPointer(); - initialize(func, restrictSet, stackReg, monitor); + Register stackPtrReg = program.getCompilerSpec().getStackPointer(); + initialize(func, restrictSet, stackPtrReg, monitor); } - /** - * initialize codeblocks and call locations. - * - * @param addressSetView - * @param monitor - * @throws CancelledException - */ private void initialize(Function func, AddressSetView restrictSet, Register reg, TaskMonitor monitor) throws CancelledException { changeMap = new DefaultIntPropertyMap("change"); @@ -177,6 +161,7 @@ public class CallDepthChangeInfo { i = changeMap.getInt(addr); } catch (NoValueException exc) { + // ignore } return i; @@ -196,6 +181,7 @@ public class CallDepthChangeInfo { depth = depthMap.getInt(addr); } catch (NoValueException exc) { + // ignore } return depth; } @@ -221,6 +207,8 @@ public class CallDepthChangeInfo { * unknown. * * @param instr instruction to analyze + * @param procContext + * @param currentStackDepth * * @return int change to stack depth if it can be determined, * Function.UNKNOWN_STACK_DEPTH_CHANGE otherwise. @@ -396,7 +384,6 @@ public class CallDepthChangeInfo { return false; } - /** * Gets the stack depth change value that has been set at the indicated address. * @@ -475,7 +462,6 @@ public class CallDepthChangeInfo { return ipm.getPropertyIterator(addressSet); } - /** * Follow the flows of the subroutine, accumulating information about the * stack pointer and any other register the stack pointer is assigned to. @@ -511,8 +497,9 @@ public class CallDepthChangeInfo { Varnode stackValue = null; try { stackValue = context.getValue(stackRegVarnode, true, this); - - if (stackValue != null && context.isSymbol(stackValue) && context.isStackSymbolicSpace(stackValue)) { + + if (stackValue != null && context.isSymbol(stackValue) && + context.isStackSymbolicSpace(stackValue)) { int stackPointerDepth = (int) stackValue.getOffset(); setDepth(instr, stackPointerDepth); } @@ -580,7 +567,6 @@ public class CallDepthChangeInfo { return; } - public int getStackPurge() { return stackPurge; } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/CaptureFunctionDataTypesCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/CaptureFunctionDataTypesCmd.java index 93587d722d..8f26916412 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/CaptureFunctionDataTypesCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/CaptureFunctionDataTypesCmd.java @@ -16,7 +16,6 @@ package ghidra.app.cmd.function; import ghidra.framework.cmd.BackgroundCommand; -import ghidra.framework.model.DomainObject; import ghidra.program.model.address.AddressSetView; import ghidra.program.model.data.*; import ghidra.program.model.listing.*; @@ -27,8 +26,8 @@ import ghidra.util.task.TaskMonitor; * Capture all selected function signature data types from the current program and put them * in the data type manager. */ -public class CaptureFunctionDataTypesCmd extends BackgroundCommand { - private Program program; +public class CaptureFunctionDataTypesCmd extends BackgroundCommand { + private DataTypeManager dtm; private AddressSetView set; private CaptureFunctionDataTypesListener listener; @@ -40,6 +39,7 @@ public class CaptureFunctionDataTypesCmd extends BackgroundCommand { * @param dtm data type manager containing the function signature data types * @param set set of addresses containing the entry points of the functions whose signatures * are to be turned into data types. + * @param listener */ public CaptureFunctionDataTypesCmd(DataTypeManager dtm, AddressSetView set, CaptureFunctionDataTypesListener listener) { @@ -49,13 +49,8 @@ public class CaptureFunctionDataTypesCmd extends BackgroundCommand { this.listener = listener; } - /** - * - * @see ghidra.framework.cmd.BackgroundCommand#applyTo(ghidra.framework.model.DomainObject, ghidra.util.task.TaskMonitor) - */ @Override - public boolean applyTo(DomainObject obj, TaskMonitor monitor) { - program = (Program) obj; + public boolean applyTo(Program program, TaskMonitor monitor) { monitor.setMessage("Capturing Function Data Types"); boolean success = false; diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/ChangeFunctionTagCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/ChangeFunctionTagCmd.java index 3d83657344..b5945f1282 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/ChangeFunctionTagCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/ChangeFunctionTagCmd.java @@ -16,14 +16,12 @@ package ghidra.app.cmd.function; import ghidra.framework.cmd.Command; -import ghidra.framework.model.DomainObject; -import ghidra.program.database.ProgramDB; import ghidra.program.model.listing.*; /** * Updates the name or comment field for a given function tag */ -public class ChangeFunctionTagCmd implements Command { +public class ChangeFunctionTagCmd implements Command { private final int field; private final String tagName; @@ -51,8 +49,8 @@ public class ChangeFunctionTagCmd implements Command { } @Override - public boolean applyTo(DomainObject obj) { - ProgramDB program = (ProgramDB) obj; + public boolean applyTo(Program program) { + FunctionManager functionManager = program.getFunctionManager(); FunctionTagManager tagManager = functionManager.getFunctionTagManager(); FunctionTag tag = tagManager.getFunctionTag(tagName); diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/CreateExternalFunctionCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/CreateExternalFunctionCmd.java index b2fab577e1..170d31613b 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/CreateExternalFunctionCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/CreateExternalFunctionCmd.java @@ -16,14 +16,13 @@ package ghidra.app.cmd.function; import ghidra.framework.cmd.Command; -import ghidra.framework.model.DomainObject; import ghidra.program.model.address.Address; import ghidra.program.model.listing.*; import ghidra.program.model.symbol.*; import ghidra.util.exception.DuplicateNameException; import ghidra.util.exception.InvalidInputException; -public class CreateExternalFunctionCmd implements Command { +public class CreateExternalFunctionCmd implements Command { private Symbol extSymbol; @@ -53,6 +52,7 @@ public class CreateExternalFunctionCmd implements Command { * @param libraryName library name, if null the UNKNOWN library will be used * @param name function name (required) * @param address the address of the function's entry point in the external library (optional) + * @param source the source type for this external function */ public CreateExternalFunctionCmd(String libraryName, String name, Address address, SourceType source) { @@ -94,8 +94,8 @@ public class CreateExternalFunctionCmd implements Command { } @Override - public boolean applyTo(DomainObject obj) { - Program program = (Program) obj; + public boolean applyTo(Program program) { + if (extSymbol == null) { return createExternalFunction(program); } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/CreateFunctionCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/CreateFunctionCmd.java index 6fe3f31532..454f424798 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/CreateFunctionCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/CreateFunctionCmd.java @@ -16,16 +16,17 @@ package ghidra.app.cmd.function; import java.util.*; +import java.util.Map.Entry; import ghidra.framework.cmd.BackgroundCommand; -import ghidra.framework.model.DomainObject; import ghidra.program.database.function.OverlappingFunctionException; import ghidra.program.model.address.*; -import ghidra.program.model.block.*; +import ghidra.program.model.block.FollowFlow; import ghidra.program.model.listing.*; import ghidra.program.model.symbol.*; import ghidra.util.Msg; -import ghidra.util.exception.*; +import ghidra.util.exception.CancelledException; +import ghidra.util.exception.InvalidInputException; import ghidra.util.task.TaskMonitor; /** @@ -33,7 +34,7 @@ import ghidra.util.task.TaskMonitor; * parameters used to create the function (Selection or just an address) and * create the function on redo and clear on undo. */ -public class CreateFunctionCmd extends BackgroundCommand { +public class CreateFunctionCmd extends BackgroundCommand { private AddressSetView origEntries; private AddressSetView origBody; @@ -143,13 +144,9 @@ public class CreateFunctionCmd extends BackgroundCommand { this(null, entry, null, SourceType.DEFAULT, findEntryPoint, false); } - /** - * - * @see ghidra.framework.cmd.BackgroundCommand#applyTo(ghidra.framework.model.DomainObject, ghidra.util.task.TaskMonitor) - */ @Override - public boolean applyTo(DomainObject obj, TaskMonitor monitor) { - program = (Program) obj; + public boolean applyTo(Program p, TaskMonitor monitor) { + program = p; Namespace globalNameSpace = program.getGlobalNamespace(); @@ -181,7 +178,7 @@ public class CreateFunctionCmd extends BackgroundCommand { extFunc = ((ExternalLocation) symObj).createFunction(); } else { - Msg.error(this, "Unexpected external symbol object: " + obj.getClass()); + Msg.error(this, "Unexpected external symbol object: " + symObj.getClass()); continue; } if (funcName != null) { @@ -210,12 +207,13 @@ public class CreateFunctionCmd extends BackgroundCommand { } monitor.setMessage("Function " + funcName); - + boolean didCreate = false; try { didCreate = createFunction(monitor, funcName, nameSpace, origEntry, origBody, tmpSource); - } catch (OverlappingFunctionException e) { + } + catch (OverlappingFunctionException e) { // try to create again, sometimes thunks can get resolved that // can't be detected, for example a thunk->function->thunk // where the final thunk gets created @@ -274,10 +272,9 @@ public class CreateFunctionCmd extends BackgroundCommand { * @throws OverlappingFunctionException if new function overlaps with existing and couldn't fix * @throws InvalidInputException bad characters in function name */ - private boolean createFunction(TaskMonitor monitor, String funcName, - Namespace nameSpace, Address entry, AddressSetView body, - SourceType nameSource) throws InvalidInputException, - OverlappingFunctionException, CancelledException { + private boolean createFunction(TaskMonitor monitor, String funcName, Namespace nameSpace, + Address entry, AddressSetView body, SourceType nameSource) + throws InvalidInputException, OverlappingFunctionException, CancelledException { FunctionManager functionMgr = program.getFunctionManager(); @@ -356,8 +353,7 @@ public class CreateFunctionCmd extends BackgroundCommand { */ private boolean createFunction(Namespace nameSpace, String funcName, Address entry, AddressSetView body, SourceType nameSource, Map bodyChangeMap, - TaskMonitor monitor) - throws OverlappingFunctionException, InvalidInputException { + TaskMonitor monitor) throws OverlappingFunctionException, InvalidInputException { Listing listing = program.getListing(); @@ -408,9 +404,9 @@ public class CreateFunctionCmd extends BackgroundCommand { * @throws CancelledException user cancelled * @throws OverlappingFunctionException existing functions overlap and couldn't reconcile */ - private static AddressSetView subtractBodyFromExisting(Program program, Address entry, AddressSetView newFuncBody, - Map bodyChangeMap, TaskMonitor monitor) - throws CancelledException, OverlappingFunctionException { + private static AddressSetView subtractBodyFromExisting(Program program, Address entry, + AddressSetView newFuncBody, Map bodyChangeMap, + TaskMonitor monitor) throws CancelledException, OverlappingFunctionException { // get all functions that overlap new function body Iterator iter = program.getFunctionManager().getFunctionsOverlapping(newFuncBody); @@ -437,26 +433,29 @@ public class CreateFunctionCmd extends BackgroundCommand { if (overlapEntryPoint.compareTo(entry) < 0) { // overlap function is before, subtract from entry to end of new function overlapEndAddr = newFuncBody.getMaxAddress(); - } else { + } + else { // overlap function is after, subtract from entry to entry of overlapping function overlapEndAddr = overlapEntryPoint.previous(); } - AddressSet overlapAddrsShouldBeInNewFunction = new AddressSet(entry,overlapEndAddr); - AddressSetView newOverlapFuncBody = overlapFuncBody.subtract(overlapAddrsShouldBeInNewFunction); + AddressSet overlapAddrsShouldBeInNewFunction = new AddressSet(entry, overlapEndAddr); + AddressSetView newOverlapFuncBody = + overlapFuncBody.subtract(overlapAddrsShouldBeInNewFunction); try { if (!overlapFuncBody.equals(newOverlapFuncBody)) { overlapFunc.setBody(newOverlapFuncBody); // set overlap body with new function body addresses removed bodyChangeMap.put(overlapFunc, overlapFuncBody); // save old overlap body } overlapFuncBody = newOverlapFuncBody; - } catch (OverlappingFunctionException oe) { + } + catch (OverlappingFunctionException oe) { // do nothing, will just subtract entire overlapping body from new function body } // remove overlapping functions body from new function body newFuncBody = newFuncBody.subtract(overlapFuncBody); } - + return newFuncBody; } @@ -524,9 +523,7 @@ public class CreateFunctionCmd extends BackgroundCommand { */ private static void restoreOriginalBodies(Map bodyChangeMap) { Set> entries = bodyChangeMap.entrySet(); - Iterator> iter = entries.iterator(); - while (iter.hasNext()) { - Map.Entry entry = iter.next(); + for (Entry entry : entries) { try { entry.getKey().setBody(entry.getValue()); } @@ -689,16 +686,16 @@ public class CreateFunctionCmd extends BackgroundCommand { func.setBody(newBody); // trigger analysis } catch (OverlappingFunctionException e) { - + Map bodyChangeMap = new HashMap<>(); try { newBody = subtractBodyFromExisting(program, entry, newBody, bodyChangeMap, monitor); - + func.setBody(newBody); // trigger analysis } catch (CancelledException | OverlappingFunctionException e1) { // something went wrong, put things back the way they were - + restoreOriginalBodies(bodyChangeMap); return false; } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/CreateFunctionDefinitionCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/CreateFunctionDefinitionCmd.java index 843713cac7..3547511b4d 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/CreateFunctionDefinitionCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/CreateFunctionDefinitionCmd.java @@ -17,7 +17,6 @@ package ghidra.app.cmd.function; import ghidra.app.services.DataTypeManagerService; import ghidra.framework.cmd.Command; -import ghidra.framework.model.DomainObject; import ghidra.framework.plugintool.ServiceProvider; import ghidra.framework.store.FileSystem; import ghidra.program.model.address.Address; @@ -28,7 +27,7 @@ import ghidra.program.model.listing.*; * Command for creating a function definition data type based on the * function signature for a function at an address. */ -public class CreateFunctionDefinitionCmd implements Command { +public class CreateFunctionDefinitionCmd implements Command { private Address entry; private final ServiceProvider serviceProvider; private String statusMsg = ""; @@ -37,28 +36,23 @@ public class CreateFunctionDefinitionCmd implements Command { * Constructs a new command for creating a function definition. * @param entry entry point address for the function whose signature is to * be used to create the function defintion data type. + * @param serviceProvider optional service provider (may be null). If specified and the + * {@link DataTypeManagerService} is found, the newly created function definition + * will be selected within the GUI. */ public CreateFunctionDefinitionCmd(Address entry, ServiceProvider serviceProvider) { this.entry = entry; this.serviceProvider = serviceProvider; } - /** - * - * @see ghidra.framework.cmd.Command#getName() - */ @Override public String getName() { return "Create Function Definition"; } - /** - * - * @see ghidra.framework.cmd.Command#applyTo(ghidra.framework.model.DomainObject) - */ @Override - public boolean applyTo(DomainObject obj) { - Program program = (Program) obj; + public boolean applyTo(Program program) { + // save off the function signature // get the body, comment, stack, return type Listing listing = program.getListing(); @@ -83,17 +77,16 @@ public class CreateFunctionDefinitionCmd implements Command { FunctionDefinitionDataType functionDef = new FunctionDefinitionDataType(sig); DataType newType = dtm.resolve(functionDef, null); - DataTypeManagerService service = serviceProvider.getService(DataTypeManagerService.class); - if (service != null) { - service.setDataTypeSelected(newType); + if (serviceProvider != null) { + DataTypeManagerService service = + serviceProvider.getService(DataTypeManagerService.class); + if (service != null) { + service.setDataTypeSelected(newType); + } } - return true; } - /** - * @see ghidra.framework.cmd.Command#getStatusMsg() - */ @Override public String getStatusMsg() { return statusMsg; diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/CreateFunctionTagCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/CreateFunctionTagCmd.java index 76fde6867b..195c8a5d41 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/CreateFunctionTagCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/CreateFunctionTagCmd.java @@ -16,15 +16,12 @@ package ghidra.app.cmd.function; import ghidra.framework.cmd.Command; -import ghidra.framework.model.DomainObject; -import ghidra.program.database.ProgramDB; -import ghidra.program.model.listing.FunctionManager; -import ghidra.program.model.listing.FunctionTagManager; +import ghidra.program.model.listing.*; /** * Command for assigning a tag to a function */ -public class CreateFunctionTagCmd implements Command { +public class CreateFunctionTagCmd implements Command { private String name; private String comment; @@ -51,8 +48,7 @@ public class CreateFunctionTagCmd implements Command { } @Override - public boolean applyTo(DomainObject obj) { - ProgramDB program = (ProgramDB) obj; + public boolean applyTo(Program program) { FunctionManager functionManager = program.getFunctionManager(); FunctionTagManager tagManager = functionManager.getFunctionTagManager(); tagManager.createFunctionTag(name, comment); diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/CreateMultipleFunctionsCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/CreateMultipleFunctionsCmd.java index 69f830cd24..e0fce57da1 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/CreateMultipleFunctionsCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/CreateMultipleFunctionsCmd.java @@ -16,7 +16,6 @@ package ghidra.app.cmd.function; import ghidra.framework.cmd.BackgroundCommand; -import ghidra.framework.model.DomainObject; import ghidra.program.model.address.*; import ghidra.program.model.listing.*; import ghidra.program.model.symbol.SourceType; @@ -31,9 +30,8 @@ import ghidra.util.task.TaskMonitor; * also discarded. * */ -public class CreateMultipleFunctionsCmd extends BackgroundCommand { +public class CreateMultipleFunctionsCmd extends BackgroundCommand { - private Program program; private AddressSetView selection; private SourceType source; @@ -44,8 +42,7 @@ public class CreateMultipleFunctionsCmd extends BackgroundCommand { } @Override - public boolean applyTo(DomainObject obj, TaskMonitor monitor) { - program = (Program) obj; + public boolean applyTo(Program program, TaskMonitor monitor) { Listing listing = program.getListing(); AddressSet addressSet = new AddressSet(selection); @@ -60,8 +57,10 @@ public class CreateMultipleFunctionsCmd extends BackgroundCommand { Function function = listing.getFunctionContaining(address); if (function == null) { // Create the next function. - Function createdFunction = createFunction(address, program, monitor); - if (createdFunction != null) { + CreateFunctionCmd createFunctionCmd = + new CreateFunctionCmd(null, address, null, source); + if (createFunctionCmd.applyTo(program, monitor)) { + function = createFunctionCmd.getFunction(); functionsCreated++; } } @@ -83,19 +82,4 @@ public class CreateMultipleFunctionsCmd extends BackgroundCommand { return true; } - /** - * Creates a function at entry point in the specified program. - * @param entryPoint the entry point of the function - * @param currentProgram the program where the function should be created - * @param monitor the task monitor that allows the user to cancel - * @return the new function or null if the function was not created - */ - public final Function createFunction(Address entryPoint, Program currentProgram, - TaskMonitor monitor) { - CreateFunctionCmd cmd = new CreateFunctionCmd(null, entryPoint, null, source); - if (cmd.applyTo(currentProgram, monitor)) { - return currentProgram.getListing().getFunctionAt(entryPoint); - } - return null; - } } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/CreateThunkFunctionCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/CreateThunkFunctionCmd.java index 9434e5acef..df33fd3a90 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/CreateThunkFunctionCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/CreateThunkFunctionCmd.java @@ -21,7 +21,6 @@ import java.util.concurrent.atomic.AtomicInteger; import ghidra.app.util.PseudoDisassembler; import ghidra.framework.cmd.BackgroundCommand; -import ghidra.framework.model.DomainObject; import ghidra.program.database.function.OverlappingFunctionException; import ghidra.program.model.address.*; import ghidra.program.model.block.*; @@ -40,7 +39,7 @@ import ghidra.util.task.TaskMonitor; /** * Command for creating a thunk function at an address. */ -public class CreateThunkFunctionCmd extends BackgroundCommand { +public class CreateThunkFunctionCmd extends BackgroundCommand { private Address entry; private AddressSetView body; private Address referencedFunctionAddr; @@ -144,8 +143,7 @@ public class CreateThunkFunctionCmd extends BackgroundCommand { } @Override - public boolean applyTo(DomainObject obj, TaskMonitor monitor) { - Program program = (Program) obj; + public boolean applyTo(Program program, TaskMonitor monitor) { FunctionManager functionMgr = program.getFunctionManager(); @@ -267,7 +265,7 @@ public class CreateThunkFunctionCmd extends BackgroundCommand { TaskMonitor monitor) { Listing listing = program.getListing(); - + if (referencedSymbol != null) { Object obj = referencedSymbol.getObject(); if (obj instanceof Function) { @@ -298,7 +296,7 @@ public class CreateThunkFunctionCmd extends BackgroundCommand { return null; } } - + // if still no thunkAddr, grab the first basic block and the call/jump at the end of the block if (referencedFunctionAddr == null || referencedFunctionAddr == Address.NO_ADDRESS) { referencedFunctionAddr = getFirstBlockJumpCall(program, monitor); @@ -387,7 +385,7 @@ public class CreateThunkFunctionCmd extends BackgroundCommand { */ private Address getFirstBlockJumpCall(Program program, TaskMonitor monitor) { SimpleBlockModel simpleBlockModel = new SimpleBlockModel(program); - + try { CodeBlock codeBlockAt = simpleBlockModel.getCodeBlockAt(entry, monitor); if (codeBlockAt == null) { @@ -401,10 +399,11 @@ public class CreateThunkFunctionCmd extends BackgroundCommand { return destRef.getDestinationAddress(); } } - } catch (CancelledException e) { + } + catch (CancelledException e) { // ignore } - + return null; } @@ -468,7 +467,8 @@ public class CreateThunkFunctionCmd extends BackgroundCommand { new ContextEvaluatorAdapter() { @Override public boolean evaluateReference(VarnodeContext context, Instruction instr, - int pcodeop, Address address, int size, DataType dataType, RefType refType) { + int pcodeop, Address address, int size, DataType dataType, + RefType refType) { // go ahead and place the reference, since it is a constant. if (refType.isComputed() && refType.isFlow() && program.getMemory().contains(address)) { @@ -494,8 +494,7 @@ public class CreateThunkFunctionCmd extends BackgroundCommand { if (value != null && program.getListing().getInstructionAt(addr) == null) { try { program.getProgramContext() - .setValue(isaModeRegister, addr, addr, - value); + .setValue(isaModeRegister, addr, addr, value); } catch (ContextChangeException e) { // ignore @@ -725,7 +724,7 @@ public class CreateThunkFunctionCmd extends BackgroundCommand { if (Math.abs(flows[0].subtract(instr.getMinAddress())) <= 8) { return true; } - + return false; } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/DeleteFunctionCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/DeleteFunctionCmd.java index dadee8884e..0f4d6ed50a 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/DeleteFunctionCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/DeleteFunctionCmd.java @@ -16,14 +16,13 @@ package ghidra.app.cmd.function; import ghidra.framework.cmd.Command; -import ghidra.framework.model.DomainObject; import ghidra.program.model.address.Address; import ghidra.program.model.listing.*; /** * Command for clearing a function at an address. */ -public class DeleteFunctionCmd implements Command { +public class DeleteFunctionCmd implements Command { private Address entry; private boolean ignoreMissingFunction; @@ -40,21 +39,14 @@ public class DeleteFunctionCmd implements Command { this.ignoreMissingFunction = ignoreMissingFunction; } - /** - * - * @see ghidra.framework.cmd.Command#getName() - */ @Override public String getName() { return "Delete Function"; } - /** - * @see ghidra.framework.cmd.Command#applyTo(ghidra.framework.model.DomainObject) - */ @Override - public boolean applyTo(DomainObject obj) { - Program program = (Program) obj; + public boolean applyTo(Program program) { + // save off the function signature // get the body, comment, stack, return type Listing listing = program.getListing(); @@ -75,9 +67,6 @@ public class DeleteFunctionCmd implements Command { return true; } - /** - * @see ghidra.framework.cmd.Command#getStatusMsg() - */ @Override public String getStatusMsg() { return ""; diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/DeleteFunctionTagCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/DeleteFunctionTagCmd.java index df09d1ac26..54f69930a0 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/DeleteFunctionTagCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/DeleteFunctionTagCmd.java @@ -16,16 +16,13 @@ package ghidra.app.cmd.function; import ghidra.framework.cmd.BackgroundCommand; -import ghidra.framework.model.DomainObject; -import ghidra.program.database.ProgramDB; -import ghidra.program.model.listing.FunctionManager; -import ghidra.program.model.listing.FunctionTag; +import ghidra.program.model.listing.*; import ghidra.util.task.TaskMonitor; /** * Command for deleting a tag from the system */ -public class DeleteFunctionTagCmd extends BackgroundCommand { +public class DeleteFunctionTagCmd extends BackgroundCommand { private String tagName; @@ -39,9 +36,7 @@ public class DeleteFunctionTagCmd extends BackgroundCommand { } @Override - public boolean applyTo(DomainObject obj, TaskMonitor monitor) { - - ProgramDB program = (ProgramDB) obj; + public boolean applyTo(Program program, TaskMonitor monitor) { FunctionManager functionManager = program.getFunctionManager(); FunctionTag tag = functionManager.getFunctionTagManager().getFunctionTag(tagName); if (tag != null) { diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/DeleteVariableCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/DeleteVariableCmd.java index 204004851d..7c85290166 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/DeleteVariableCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/DeleteVariableCmd.java @@ -1,6 +1,5 @@ /* ### * IP: GHIDRA - * REVIEWED: YES * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,43 +16,46 @@ package ghidra.app.cmd.function; import ghidra.framework.cmd.Command; -import ghidra.framework.model.DomainObject; import ghidra.program.model.listing.*; /** * Command for deleting a variable in a function. */ -public class DeleteVariableCmd implements Command { - - private Variable var; - - public DeleteVariableCmd(Variable var) { - this.var = var; - } - +public class DeleteVariableCmd implements Command { + + private Variable var; + + public DeleteVariableCmd(Variable var) { + this.var = var; + } + /** * * @see ghidra.framework.cmd.Command#getName() */ - public String getName() { - return "Delete " + (var instanceof Parameter ? "Parameter" : "Variable"); - } - + @Override + public String getName() { + return "Delete " + (var instanceof Parameter ? "Parameter" : "Variable"); + } + /** * * @see ghidra.framework.cmd.Command#applyTo(ghidra.framework.model.DomainObject) - */ - public boolean applyTo(DomainObject obj) { + */ + @Override + public boolean applyTo(Program program) { Function f = var.getFunction(); + if (f == null || f.getProgram() != program) { + return false; + } f.removeVariable(var); return true; } - - /** * @see ghidra.framework.cmd.Command#getStatusMsg() */ + @Override public String getStatusMsg() { return ""; } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/FunctionPurgeAnalysisCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/FunctionPurgeAnalysisCmd.java index a8afb92bcd..8f0ad57ab4 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/FunctionPurgeAnalysisCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/FunctionPurgeAnalysisCmd.java @@ -16,7 +16,6 @@ package ghidra.app.cmd.function; import ghidra.framework.cmd.BackgroundCommand; -import ghidra.framework.model.DomainObject; import ghidra.program.model.address.*; import ghidra.program.model.lang.Processor; import ghidra.program.model.lang.PrototypeModel; @@ -32,7 +31,7 @@ import ghidra.util.task.TaskMonitor; /** * Command for analyzing the Stack; the command is run in the background. */ -public class FunctionPurgeAnalysisCmd extends BackgroundCommand { +public class FunctionPurgeAnalysisCmd extends BackgroundCommand { private AddressSetView entryPoints; private Program program; private PrototypeModel[] nearFarModels = null; @@ -52,13 +51,9 @@ public class FunctionPurgeAnalysisCmd extends BackgroundCommand { entryPoints = entries; } - /** - * - * @see ghidra.framework.cmd.BackgroundCommand#applyTo(ghidra.framework.model.DomainObject, ghidra.util.task.TaskMonitor) - */ @Override - public boolean applyTo(DomainObject obj, TaskMonitor monitor) { - program = (Program) obj; + public boolean applyTo(Program p, TaskMonitor monitor) { + program = p; Processor processor = program.getLanguage().getProcessor(); AddressSpace defaultSpace = program.getLanguage().getDefaultSpace(); diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/FunctionResultStateStackAnalysisCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/FunctionResultStateStackAnalysisCmd.java index 2ad2a70d3f..978a573a30 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/FunctionResultStateStackAnalysisCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/FunctionResultStateStackAnalysisCmd.java @@ -18,7 +18,6 @@ package ghidra.app.cmd.function; import java.util.*; import ghidra.framework.cmd.BackgroundCommand; -import ghidra.framework.model.DomainObject; import ghidra.program.model.address.*; import ghidra.program.model.data.DataType; import ghidra.program.model.data.Undefined; @@ -31,12 +30,11 @@ import ghidra.util.Msg; import ghidra.util.exception.*; import ghidra.util.state.*; import ghidra.util.task.TaskMonitor; -import ghidra.util.task.TaskMonitorAdapter; /** * Command for analyzing the Stack; the command is run in the background. */ -public class FunctionResultStateStackAnalysisCmd extends BackgroundCommand { +public class FunctionResultStateStackAnalysisCmd extends BackgroundCommand { private AddressSet entryPoints = new AddressSet(); private boolean forceProcessing = false; private boolean dontCreateNewVariables = false; @@ -65,13 +63,8 @@ public class FunctionResultStateStackAnalysisCmd extends BackgroundCommand { this(new AddressSet(entry, entry), forceProcessing); } - /** - * - * @see ghidra.framework.cmd.BackgroundCommand#applyTo(ghidra.framework.model.DomainObject, ghidra.util.task.TaskMonitor) - */ @Override - public boolean applyTo(DomainObject obj, TaskMonitor monitor) { - Program program = (Program) obj; + public boolean applyTo(Program program, TaskMonitor monitor) { int count = 0; monitor.initialize(entryPoints.getNumAddresses()); @@ -335,14 +328,11 @@ public class FunctionResultStateStackAnalysisCmd extends BackgroundCommand { for (SequenceNumber seq : results.getReturnAddresses()) { ContextState returnState = results.getContextStates(seq).next(); Varnode varnode = - returnState.get(results.getStackPointerVarnode(), - TaskMonitor.DUMMY); - Varnode zero = - new Varnode(addrFactory.getConstantSpace().getAddress(0), - stackReg.getMinimumByteSize()); - varnode = - replaceInputVarnodes(varnode, results.getStackPointerVarnode(), zero, 4, - monitor); + returnState.get(results.getStackPointerVarnode(), TaskMonitor.DUMMY); + Varnode zero = new Varnode(addrFactory.getConstantSpace().getAddress(0), + stackReg.getMinimumByteSize()); + varnode = replaceInputVarnodes(varnode, results.getStackPointerVarnode(), zero, 4, + monitor); if (varnode == null) { continue; } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/FunctionStackAnalysisCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/FunctionStackAnalysisCmd.java index 726ac988c5..5a9d32933a 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/FunctionStackAnalysisCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/FunctionStackAnalysisCmd.java @@ -15,8 +15,10 @@ */ package ghidra.app.cmd.function; +import java.util.ArrayList; +import java.util.Stack; + import ghidra.framework.cmd.BackgroundCommand; -import ghidra.framework.model.DomainObject; import ghidra.program.model.address.*; import ghidra.program.model.data.*; import ghidra.program.model.lang.Register; @@ -28,14 +30,11 @@ import ghidra.util.Msg; import ghidra.util.exception.*; import ghidra.util.task.TaskMonitor; -import java.util.ArrayList; -import java.util.Stack; - /** * Command for analyzing the Stack; the command is run in the background. * NOTE: referenced thunk-functions should be created prior to this command */ -public class FunctionStackAnalysisCmd extends BackgroundCommand { +public class FunctionStackAnalysisCmd extends BackgroundCommand { private AddressSet entryPoints = new AddressSet(); private Program program; private boolean forceProcessing = false; @@ -76,13 +75,9 @@ public class FunctionStackAnalysisCmd extends BackgroundCommand { doLocals = doLocalAnalysis; } - /** - * - * @see ghidra.framework.cmd.BackgroundCommand#applyTo(ghidra.framework.model.DomainObject, ghidra.util.task.TaskMonitor) - */ @Override - public boolean applyTo(DomainObject obj, TaskMonitor monitor) { - program = (Program) obj; + public boolean applyTo(Program p, TaskMonitor monitor) { + program = p; int count = 0; monitor.initialize(entryPoints.getNumAddresses()); @@ -285,7 +280,8 @@ public class FunctionStackAnalysisCmd extends BackgroundCommand { // return true; // } - private void defineFuncVariable(Function func, Instruction instr, int opIndex, int stackOffset) { + private void defineFuncVariable(Function func, Instruction instr, int opIndex, + int stackOffset) { ReferenceManager refMgr = program.getReferenceManager(); @@ -365,9 +361,8 @@ public class FunctionStackAnalysisCmd extends BackgroundCommand { return null; } // only create variables at locations where a variable doesn't exist - var = - frame.createVariable(null, frameLoc, Undefined.getUndefinedDataType(refSize), - SourceType.ANALYSIS); + var = frame.createVariable(null, frameLoc, Undefined.getUndefinedDataType(refSize), + SourceType.ANALYSIS); } catch (DuplicateNameException e) { throw new AssertException(e); diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/NewFunctionStackAnalysisCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/NewFunctionStackAnalysisCmd.java index f4c7602648..337b84252d 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/NewFunctionStackAnalysisCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/NewFunctionStackAnalysisCmd.java @@ -19,7 +19,6 @@ import java.math.BigInteger; import java.util.*; import ghidra.framework.cmd.BackgroundCommand; -import ghidra.framework.model.DomainObject; import ghidra.program.model.address.*; import ghidra.program.model.data.DataType; import ghidra.program.model.data.Undefined; @@ -39,7 +38,7 @@ import ghidra.util.task.TaskMonitor; * Command for analyzing the Stack; the command is run in the background. * NOTE: referenced thunk-functions should be created prior to this command */ -public class NewFunctionStackAnalysisCmd extends BackgroundCommand { +public class NewFunctionStackAnalysisCmd extends BackgroundCommand { private static final int MAX_PARAM_OFFSET = 2048; // max size of param reference space private static final int MAX_LOCAL_OFFSET = -(64 * 1024); // max size of local reference space @@ -86,13 +85,9 @@ public class NewFunctionStackAnalysisCmd extends BackgroundCommand { doLocals = doLocalAnalysis; } - /** - * - * @see ghidra.framework.cmd.BackgroundCommand#applyTo(ghidra.framework.model.DomainObject, ghidra.util.task.TaskMonitor) - */ @Override - public boolean applyTo(DomainObject obj, TaskMonitor monitor) { - program = (Program) obj; + public boolean applyTo(Program p, TaskMonitor monitor) { + program = p; int count = 0; long numAddresses = entryPoints.getNumAddresses(); @@ -133,7 +128,7 @@ public class NewFunctionStackAnalysisCmd extends BackgroundCommand { /** * Analyze a function to build a stack frame based on stack references. * - * @param entry The address of the entry point for the new function + * @param f function to analyze * @param monitor the task monitor that is checked to see if the command has * been cancelled. * @throws CancelledException if the user canceled this command @@ -164,9 +159,8 @@ public class NewFunctionStackAnalysisCmd extends BackgroundCommand { // Later this should change to stack locked. Variable[] variables = func.getVariables(VariableFilter.STACK_VARIABLE_FILTER); boolean hasReferences = false; - for (int i = 0; i < variables.length; i++) { - Reference[] referencesTo = - program.getReferenceManager().getReferencesTo(variables[i]); + for (Variable variable : variables) { + Reference[] referencesTo = program.getReferenceManager().getReferencesTo(variable); if (referencesTo.length != 0) { hasReferences = true; break; @@ -599,13 +593,13 @@ public class NewFunctionStackAnalysisCmd extends BackgroundCommand { return -1; } - /** - * Checks the indicated function in the program to determine if it is a jump thunk - * through a function pointer. - * @param func the function to check - * @param monitor status monitor for indicating progress and allowing cancel. - * @returntrue if check if this is a jump thunk through a function pointer - */ +// /** +// * Checks the indicated function in the program to determine if it is a jump thunk +// * through a function pointer. +// * @param func the function to check +// * @param monitor status monitor for indicating progress and allowing cancel. +// * @returntrue if check if this is a jump thunk through a function pointer +// */ // private boolean checkThunk(Function func, TaskMonitor monitor) { // Instruction instr = program.getListing().getInstructionAt(func.getEntryPoint()); // if (instr == null) { diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/RemoveFunctionTagCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/RemoveFunctionTagCmd.java index 2b42e078d7..117129dee5 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/RemoveFunctionTagCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/RemoveFunctionTagCmd.java @@ -16,16 +16,13 @@ package ghidra.app.cmd.function; import ghidra.framework.cmd.Command; -import ghidra.framework.model.DomainObject; -import ghidra.program.database.ProgramDB; import ghidra.program.model.address.Address; -import ghidra.program.model.listing.Function; -import ghidra.program.model.listing.FunctionManager; +import ghidra.program.model.listing.*; /** * Command for removing a tag from a function */ -public class RemoveFunctionTagCmd implements Command { +public class RemoveFunctionTagCmd implements Command { private Address entryPoint; private String tagName; @@ -42,8 +39,7 @@ public class RemoveFunctionTagCmd implements Command { } @Override - public boolean applyTo(DomainObject obj) { - ProgramDB program = (ProgramDB) obj; + public boolean applyTo(Program program) { FunctionManager functionManager = program.getFunctionManager(); Function function = functionManager.getFunctionAt(entryPoint); function.removeTag(tagName); diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/RemoveStackDepthChangeCommand.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/RemoveStackDepthChangeCommand.java index a96affbf47..a81d0854b0 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/RemoveStackDepthChangeCommand.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/RemoveStackDepthChangeCommand.java @@ -1,6 +1,5 @@ /* ### * IP: GHIDRA - * REVIEWED: YES * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,28 +16,28 @@ package ghidra.app.cmd.function; import ghidra.framework.cmd.Command; -import ghidra.framework.model.DomainObject; import ghidra.program.model.address.Address; import ghidra.program.model.listing.Program; -public class RemoveStackDepthChangeCommand implements Command { - - private Program program; +public class RemoveStackDepthChangeCommand implements Command { + private Address address; - - public RemoveStackDepthChangeCommand(Program program, Address address) { - this.program = program; + + public RemoveStackDepthChangeCommand(Address address) { this.address = address; } - public boolean applyTo(DomainObject obj) { + @Override + public boolean applyTo(Program program) { return CallDepthChangeInfo.removeStackDepthChange(program, address); } + @Override public String getName() { return "Remove Stack Depth Change"; } + @Override public String getStatusMsg() { return null; } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/SetFunctionNameCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/SetFunctionNameCmd.java index 7eca15157f..7d53d724d2 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/SetFunctionNameCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/SetFunctionNameCmd.java @@ -1,6 +1,5 @@ /* ### * IP: GHIDRA - * REVIEWED: YES * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,7 +16,6 @@ package ghidra.app.cmd.function; import ghidra.framework.cmd.Command; -import ghidra.framework.model.DomainObject; import ghidra.program.model.address.Address; import ghidra.program.model.listing.Function; import ghidra.program.model.listing.Program; @@ -26,37 +24,35 @@ import ghidra.program.model.symbol.SourceType; /** * Command to set the name of a function. */ -public class SetFunctionNameCmd implements Command { - private Address entry; - private String name; - private String msg; +public class SetFunctionNameCmd implements Command { + private Address entry; + private String name; + private String msg; private SourceType source; - /** - * Constructs a new command for setting the name of a function. - * @param entry the address of the function to be renamed. - * @param newName the new name for the function. + + /** + * Constructs a new command for setting the name of a function. + * @param entry the address of the function to be renamed. + * @param newName the new name for the function. * @param source the source of this function name - */ - public SetFunctionNameCmd(Address entry, String newName, SourceType source) { - this.entry = entry; + */ + public SetFunctionNameCmd(Address entry, String newName, SourceType source) { + this.entry = entry; this.name = newName; this.source = source; - } - /** - * - * @see ghidra.framework.cmd.Command#applyTo(ghidra.framework.model.DomainObject) - */ - public boolean applyTo(DomainObject obj) { - Program program = (Program)obj; - - if (name.length() <= 0) { - name = null; - } + } - Function f = program.getListing().getFunctionAt(entry); - if (f == null) { - return true; - } + @Override + public boolean applyTo(Program program) { + + if (name.length() <= 0) { + name = null; + } + + Function f = program.getListing().getFunctionAt(entry); + if (f == null) { + return true; + } try { f.setName(name, source); } @@ -66,20 +62,14 @@ public class SetFunctionNameCmd implements Command { } return true; - } - - /** - * - * @see ghidra.framework.cmd.Command#getName() - */ - public String getName() { - return "Rename Function"; - } - - - /** - * @see ghidra.framework.cmd.Command#getStatusMsg() - */ + } + + @Override + public String getName() { + return "Rename Function"; + } + + @Override public String getStatusMsg() { return msg; } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/SetFunctionPurgeCommand.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/SetFunctionPurgeCommand.java index cdc169ea37..19ac8e9de4 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/SetFunctionPurgeCommand.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/SetFunctionPurgeCommand.java @@ -1,6 +1,5 @@ /* ### * IP: GHIDRA - * REVIEWED: YES * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,8 +16,8 @@ package ghidra.app.cmd.function; import ghidra.framework.cmd.Command; -import ghidra.framework.model.DomainObject; import ghidra.program.model.listing.Function; +import ghidra.program.model.listing.Program; /** * A simple command to set the stack purge size of a function. @@ -26,41 +25,35 @@ import ghidra.program.model.listing.Function; * * @since Tracker Id 548 */ -public class SetFunctionPurgeCommand implements Command { - private Function function; - private int functionPurge; - - /** - * Creates a new command that will set the given purge size on the given - * function. - * - * @param function The function on which to set the purge size. - * @param newPurge The new stack purge size. - */ - public SetFunctionPurgeCommand( Function function, int newPurge ) { - this.function = function; - this.functionPurge = newPurge; - } +public class SetFunctionPurgeCommand implements Command { + private Function function; + private int functionPurge; - /** - * @see ghidra.framework.cmd.Command#applyTo(ghidra.framework.model.DomainObject) - */ - public boolean applyTo(DomainObject obj) { - function.setStackPurgeSize( functionPurge ); - return true; - } + /** + * Creates a new command that will set the given purge size on the given + * function. + * + * @param function The function on which to set the purge size. + * @param newPurge The new stack purge size. + */ + public SetFunctionPurgeCommand(Function function, int newPurge) { + this.function = function; + this.functionPurge = newPurge; + } - /** - * @see ghidra.framework.cmd.Command#getStatusMsg() - */ - public String getStatusMsg() { - return ""; - } + @Override + public boolean applyTo(Program program) { + function.setStackPurgeSize(functionPurge); + return true; + } - /** - * @see ghidra.framework.cmd.Command#getName() - */ - public String getName() { - return "Set Function Purge"; - } + @Override + public String getStatusMsg() { + return ""; + } + + @Override + public String getName() { + return "Set Function Purge"; + } } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/SetFunctionRepeatableCommentCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/SetFunctionRepeatableCommentCmd.java index 2674e7910f..20f7a3e0e6 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/SetFunctionRepeatableCommentCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/SetFunctionRepeatableCommentCmd.java @@ -1,6 +1,5 @@ /* ### * IP: GHIDRA - * REVIEWED: YES * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,7 +16,6 @@ package ghidra.app.cmd.function; import ghidra.framework.cmd.Command; -import ghidra.framework.model.DomainObject; import ghidra.program.model.address.Address; import ghidra.program.model.listing.Function; import ghidra.program.model.listing.Program; @@ -25,44 +23,35 @@ import ghidra.program.model.listing.Program; /** * Command to set the Function's Repeatable Comment. */ -public class SetFunctionRepeatableCommentCmd implements Command { - private Address entry; - private String newRepeatableComment; - - /** - * Constructs a new command for setting the Repeatable comment. - * @param entry address of the function for which to set a Repeatablecomment. - * @param newRepeatableComment comment to set as the function Repeatable comment. - */ - public SetFunctionRepeatableCommentCmd(Address entry, String newRepeatableComment) { - this.entry = entry; - this.newRepeatableComment = newRepeatableComment; - } - - /** - * - * @see ghidra.framework.cmd.Command#getName() - */ - public String getName() { - return "Set Function Repeatable Comment"; - } - - /** - * - * @see ghidra.framework.cmd.Command#applyTo(ghidra.framework.model.DomainObject) - */ - public boolean applyTo(DomainObject obj) { - Program program = (Program)obj; - Function f = program.getListing().getFunctionAt(entry); - if (f != null) { - f.setRepeatableComment(newRepeatableComment); - } - return true; - } +public class SetFunctionRepeatableCommentCmd implements Command { + private Address entry; + private String newRepeatableComment; /** - * @see ghidra.framework.cmd.Command#getStatusMsg() + * Constructs a new command for setting the Repeatable comment. + * @param entry address of the function for which to set a Repeatablecomment. + * @param newRepeatableComment comment to set as the function Repeatable comment. */ + public SetFunctionRepeatableCommentCmd(Address entry, String newRepeatableComment) { + this.entry = entry; + this.newRepeatableComment = newRepeatableComment; + } + + @Override + public String getName() { + return "Set Function Repeatable Comment"; + } + + @Override + public boolean applyTo(Program program) { + Function f = program.getListing().getFunctionAt(entry); + if (f != null) { + f.setRepeatableComment(newRepeatableComment); + } + return true; + } + + @Override public String getStatusMsg() { return ""; } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/SetFunctionVarArgsCommand.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/SetFunctionVarArgsCommand.java index e7697b418e..2483bea414 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/SetFunctionVarArgsCommand.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/SetFunctionVarArgsCommand.java @@ -1,6 +1,5 @@ /* ### * IP: GHIDRA - * REVIEWED: YES * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,47 +16,41 @@ package ghidra.app.cmd.function; import ghidra.framework.cmd.Command; -import ghidra.framework.model.DomainObject; import ghidra.program.model.listing.Function; +import ghidra.program.model.listing.Program; /** * A simple command to set whether or not a function has VarArgs. */ -public class SetFunctionVarArgsCommand implements Command { - private Function function; - private boolean hasVarArgs; - - /** - * Creates a new command that will set whether or not there are VarArgs on the given - * function. - * - * @param function The function on which to set whether or not there are VarArgs. - * @param hasVarArgs true if you want to set this function to have VarArgs. - */ - public SetFunctionVarArgsCommand( Function function, boolean hasVarArgs ) { - this.function = function; - this.hasVarArgs = hasVarArgs; - } +public class SetFunctionVarArgsCommand implements Command { + private Function function; + private boolean hasVarArgs; - /** - * @see ghidra.framework.cmd.Command#applyTo(ghidra.framework.model.DomainObject) - */ - public boolean applyTo(DomainObject obj) { - function.setVarArgs( hasVarArgs ); - return true; - } + /** + * Creates a new command that will set whether or not there are VarArgs on the given + * function. + * + * @param function The function on which to set whether or not there are VarArgs. + * @param hasVarArgs true if you want to set this function to have VarArgs. + */ + public SetFunctionVarArgsCommand(Function function, boolean hasVarArgs) { + this.function = function; + this.hasVarArgs = hasVarArgs; + } - /** - * @see ghidra.framework.cmd.Command#getStatusMsg() - */ - public String getStatusMsg() { - return ""; - } + @Override + public boolean applyTo(Program program) { + function.setVarArgs(hasVarArgs); + return true; + } - /** - * @see ghidra.framework.cmd.Command#getName() - */ - public String getName() { - return "Set Function VarArgs"; - } + @Override + public String getStatusMsg() { + return ""; + } + + @Override + public String getName() { + return "Set Function VarArgs"; + } } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/SetReturnDataTypeCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/SetReturnDataTypeCmd.java index 18ccf173b7..4110c76af0 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/SetReturnDataTypeCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/SetReturnDataTypeCmd.java @@ -1,6 +1,5 @@ /* ### * IP: GHIDRA - * REVIEWED: YES * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,7 +16,6 @@ package ghidra.app.cmd.function; import ghidra.framework.cmd.Command; -import ghidra.framework.model.DomainObject; import ghidra.program.model.address.Address; import ghidra.program.model.data.DataType; import ghidra.program.model.listing.Function; @@ -28,7 +26,7 @@ import ghidra.util.exception.InvalidInputException; /** * Command for setting a function's return type. */ -public class SetReturnDataTypeCmd implements Command { +public class SetReturnDataTypeCmd implements Command { private Address entry; private DataType dataType; private String status; @@ -46,22 +44,13 @@ public class SetReturnDataTypeCmd implements Command { this.source = source; } - /** - * - * @see ghidra.framework.cmd.Command#getName() - */ @Override public String getName() { return "Set Return Data Type"; } - /** - * - * @see ghidra.framework.cmd.Command#applyTo(ghidra.framework.model.DomainObject) - */ @Override - public boolean applyTo(DomainObject obj) { - Program program = (Program) obj; + public boolean applyTo(Program program) { Function function = program.getListing().getFunctionAt(entry); try { function.setReturnType(dataType, source); @@ -76,9 +65,6 @@ public class SetReturnDataTypeCmd implements Command { return true; } - /** - * @see ghidra.framework.cmd.Command#getStatusMsg() - */ @Override public String getStatusMsg() { return status; diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/SetStackDepthChangeCommand.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/SetStackDepthChangeCommand.java index 769c9f57ed..7d01673d42 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/SetStackDepthChangeCommand.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/SetStackDepthChangeCommand.java @@ -1,6 +1,5 @@ /* ### * IP: GHIDRA - * REVIEWED: YES * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,40 +16,41 @@ package ghidra.app.cmd.function; import ghidra.framework.cmd.Command; -import ghidra.framework.model.DomainObject; import ghidra.program.model.address.Address; import ghidra.program.model.listing.Program; import ghidra.util.Msg; import ghidra.util.exception.DuplicateNameException; -public class SetStackDepthChangeCommand implements Command { - - private Program program; +public class SetStackDepthChangeCommand implements Command { + private Address address; private int stackDepthChange; private String errMsg = null; - - public SetStackDepthChangeCommand(Program program, Address address, int newStackDepthChange) { - this.program = program; + + public SetStackDepthChangeCommand(Address address, int newStackDepthChange) { this.address = address; this.stackDepthChange = newStackDepthChange; } - - public boolean applyTo(DomainObject obj) { + + @Override + public boolean applyTo(Program program) { try { CallDepthChangeInfo.setStackDepthChange(program, address, stackDepthChange); return true; - } catch (DuplicateNameException e) { + } + catch (DuplicateNameException e) { errMsg = e.getMessage(); Msg.error(this, "Unexpected Exception: " + e.getMessage(), e); return false; } } + @Override public String getName() { return "Set Stack Depth Change"; } + @Override public String getStatusMsg() { return errMsg; } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/SetVariableCommentCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/SetVariableCommentCmd.java index 81e269d953..7100b6288d 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/SetVariableCommentCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/SetVariableCommentCmd.java @@ -1,6 +1,5 @@ /* ### * IP: GHIDRA - * REVIEWED: YES * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,49 +16,39 @@ package ghidra.app.cmd.function; import ghidra.framework.cmd.Command; -import ghidra.framework.model.DomainObject; +import ghidra.program.model.listing.Program; import ghidra.program.model.listing.Variable; - /** * Command to set the comment on a function varible. */ -public class SetVariableCommentCmd implements Command { +public class SetVariableCommentCmd implements Command { private Variable var; - private String comment; - private String msg; - - /** - * Constructs a new command for setting the comment on a function variable. - * @param var the variable on which to set the comment. - * @param newComment the comment string to set on the specified variable. - */ - public SetVariableCommentCmd(Variable var, String newComment) { - this.var = var; - this.comment = newComment; - } - - /** - * - * @see ghidra.framework.cmd.Command#getName() - */ - public String getName() { - return "Set Variable Comment"; - } - - /** - * - * @see ghidra.framework.cmd.Command#applyTo(ghidra.framework.model.DomainObject) - */ - public boolean applyTo(DomainObject obj) { - var.setComment(comment); - return true; - } - + private String comment; + private String msg; /** - * @see ghidra.framework.cmd.Command#getStatusMsg() + * Constructs a new command for setting the comment on a function variable. + * @param var the variable on which to set the comment. + * @param newComment the comment string to set on the specified variable. */ + public SetVariableCommentCmd(Variable var, String newComment) { + this.var = var; + this.comment = newComment; + } + + @Override + public String getName() { + return "Set Variable Comment"; + } + + @Override + public boolean applyTo(Program program) { + var.setComment(comment); + return true; + } + + @Override public String getStatusMsg() { return msg; } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/SetVariableDataTypeCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/SetVariableDataTypeCmd.java index a0b8dcabe1..68fb70aba1 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/SetVariableDataTypeCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/SetVariableDataTypeCmd.java @@ -16,7 +16,6 @@ package ghidra.app.cmd.function; import ghidra.framework.cmd.Command; -import ghidra.framework.model.DomainObject; import ghidra.program.model.address.Address; import ghidra.program.model.data.*; import ghidra.program.model.listing.*; @@ -27,7 +26,7 @@ import ghidra.util.exception.InvalidInputException; /** * Command to set the datatype on a stack variable. */ -public class SetVariableDataTypeCmd implements Command { +public class SetVariableDataTypeCmd implements Command { private final Address fnEntry; private final String varName; @@ -86,10 +85,6 @@ public class SetVariableDataTypeCmd implements Command { this.source = source; } - /** - * - * @see ghidra.framework.cmd.Command#getName() - */ @Override public String getName() { return "Set " + (isParm ? "Parameter" : "Variable") + " Data Type"; @@ -100,21 +95,16 @@ public class SetVariableDataTypeCmd implements Command { * @see ghidra.framework.cmd.Command#applyTo(ghidra.framework.model.DomainObject) */ @Override - public boolean applyTo(DomainObject obj) { - if (!(obj instanceof Program)) { - return false; - } - Program p = (Program) obj; - - Function f = p.getFunctionManager().getFunctionAt(fnEntry); + public boolean applyTo(Program program) { + Function f = program.getFunctionManager().getFunctionAt(fnEntry); if (f == null) { status = "Function not found"; return false; } - Symbol s = p.getSymbolTable().getParameterSymbol(varName, f); + Symbol s = program.getSymbolTable().getParameterSymbol(varName, f); if (s == null) { - s = p.getSymbolTable().getLocalVariableSymbol(varName, f); + s = program.getSymbolTable().getLocalVariableSymbol(varName, f); } if (s == null) { status = "Variable not found"; diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/SetVariableNameCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/SetVariableNameCmd.java index 29e3731611..61eb6c7999 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/SetVariableNameCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/SetVariableNameCmd.java @@ -16,7 +16,6 @@ package ghidra.app.cmd.function; import ghidra.framework.cmd.Command; -import ghidra.framework.model.DomainObject; import ghidra.program.model.address.Address; import ghidra.program.model.listing.*; import ghidra.program.model.symbol.SourceType; @@ -27,7 +26,7 @@ import ghidra.util.exception.InvalidInputException; /** * Command to rename a stack variable. */ -public class SetVariableNameCmd implements Command { +public class SetVariableNameCmd implements Command { private Address fnEntry; private String varName; @@ -64,27 +63,18 @@ public class SetVariableNameCmd implements Command { this.source = source; } - /** - * - * @see ghidra.framework.cmd.Command#applyTo(ghidra.framework.model.DomainObject) - */ @Override - public boolean applyTo(DomainObject obj) { + public boolean applyTo(Program program) { - if (!(obj instanceof Program)) { - return false; - } - Program p = (Program) obj; - - Function f = p.getFunctionManager().getFunctionAt(fnEntry); + Function f = program.getFunctionManager().getFunctionAt(fnEntry); if (f == null) { status = "Function not found"; return false; } - Symbol s = p.getSymbolTable().getParameterSymbol(varName, f); + Symbol s = program.getSymbolTable().getParameterSymbol(varName, f); if (s == null) { - s = p.getSymbolTable().getLocalVariableSymbol(varName, f); + s = program.getSymbolTable().getLocalVariableSymbol(varName, f); } if (s == null) { status = "Variable not found"; @@ -106,17 +96,11 @@ public class SetVariableNameCmd implements Command { return false; } - /** - * @see ghidra.framework.cmd.Command#getStatusMsg() - */ @Override public String getStatusMsg() { return status; } - /** - * @see ghidra.framework.cmd.Command#getName() - */ @Override public String getName() { return "Rename " + (isParm ? "Parameter" : "Variable"); diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/UpdateFunctionCommand.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/UpdateFunctionCommand.java new file mode 100644 index 0000000000..5dd102ecdb --- /dev/null +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/UpdateFunctionCommand.java @@ -0,0 +1,101 @@ +/* ### + * IP: GHIDRA + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ghidra.app.cmd.function; + +import java.util.List; + +import ghidra.framework.cmd.Command; +import ghidra.program.model.listing.*; +import ghidra.program.model.listing.Function.FunctionUpdateType; +import ghidra.program.model.symbol.SourceType; +import ghidra.util.exception.DuplicateNameException; +import ghidra.util.exception.InvalidInputException; + +/** + * A command to update {@link Function} signature in its entirety including optional + * custom storage. + * + * If the function does not rely on custom storage the use of {@link ApplyFunctionSignatureCmd} + * may be more appropriate. + */ +public class UpdateFunctionCommand implements Command { + + private final Function function; + private final FunctionUpdateType updateType; + private final String callingConvention; + private final Variable returnVar; + private final List params; + private final SourceType source; + private final boolean force; + + private String statusMessage; + + /** + * Construct command to update a {@link Function} signature including optional custom storage. + * {@link VariableStorage#UNASSIGNED_STORAGE} should be specified when not using custom storage + * or storage is unknown. + * + * @param function function to be modified + * @param updateType indicates how function should be updated including the use of custom or + * non-custom storage. + * @param callingConvention a valid calling convention name or null if no change is required. + * Calling conventions are limited to {@value Function#DEFAULT_CALLING_CONVENTION_STRING}, + * {@value Function#UNKNOWN_CALLING_CONVENTION_STRING} or those defined by the associated + * compiler specification. + * @param returnVar function return type and storage. + * @param params function parameter list (specifics depend on specified + * {@link FunctionUpdateType updateType}). + * @param source the source of these parameters which will be applied to the parameter + * symbols and overall function signature source. If parameter names are null, or a default + * name, a {@link SourceType#DEFAULT} will be applied to the corresponding parameter symbol. + * @param force if true any conflicting local parameters will be removed + */ + public UpdateFunctionCommand(Function function, FunctionUpdateType updateType, + String callingConvention, Variable returnVar, List params, + SourceType source, boolean force) { + this.function = function; + this.updateType = updateType; + this.callingConvention = callingConvention; + this.returnVar = returnVar; + this.params = params; + this.source = source; + this.force = force; + } + + @Override + public boolean applyTo(Program obj) { + try { + function.updateFunction(callingConvention, returnVar, params, updateType, force, + source); + return true; + } + catch (InvalidInputException | DuplicateNameException e) { + statusMessage = e.getMessage(); + return false; + } + } + + @Override + public String getStatusMsg() { + return statusMessage; + } + + @Override + public String getName() { + return "Update Function"; + } + +} diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/label/AddLabelCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/label/AddLabelCmd.java index 3af98e638a..5701247bf0 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/label/AddLabelCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/label/AddLabelCmd.java @@ -16,7 +16,6 @@ package ghidra.app.cmd.label; import ghidra.framework.cmd.Command; -import ghidra.framework.model.DomainObject; import ghidra.program.model.address.Address; import ghidra.program.model.listing.Program; import ghidra.program.model.symbol.*; @@ -25,7 +24,7 @@ import ghidra.util.exception.InvalidInputException; /** * Command to add a label. */ -public class AddLabelCmd implements Command { +public class AddLabelCmd implements Command { private Address addr; private String name; private Namespace namespace; @@ -76,13 +75,9 @@ public class AddLabelCmd implements Command { this(addr, name, null, source); } - /** - * - * @see ghidra.framework.cmd.Command#applyTo(ghidra.framework.model.DomainObject) - */ @Override - public boolean applyTo(DomainObject obj) { - SymbolTable st = ((Program) obj).getSymbolTable(); + public boolean applyTo(Program program) { + SymbolTable st = program.getSymbolTable(); if (namespace == null && useLocalNamespace) { namespace = st.getNamespace(addr); } @@ -103,17 +98,11 @@ public class AddLabelCmd implements Command { } - /** - * @see ghidra.framework.cmd.Command#getStatusMsg() - */ @Override public String getStatusMsg() { return errorMsg; } - /** - * @see ghidra.framework.cmd.Command#getName() - */ @Override public String getName() { return "Add Label"; diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/label/AddUniqueLabelCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/label/AddUniqueLabelCmd.java index 5ecbab3247..32e316d4e8 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/label/AddUniqueLabelCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/label/AddUniqueLabelCmd.java @@ -16,7 +16,6 @@ package ghidra.app.cmd.label; import ghidra.framework.cmd.Command; -import ghidra.framework.model.DomainObject; import ghidra.program.model.address.Address; import ghidra.program.model.listing.Program; import ghidra.program.model.symbol.*; @@ -29,7 +28,7 @@ import ghidra.util.exception.InvalidInputException; * @deprecated The need for this class is now unnecessary since duplicate labels are permitted */ @Deprecated -public class AddUniqueLabelCmd implements Command { +public class AddUniqueLabelCmd implements Command { private Address address; private String name; private Namespace namespace; @@ -52,12 +51,9 @@ public class AddUniqueLabelCmd implements Command { this.source = source; } - /** - * @see ghidra.framework.cmd.Command#applyTo(ghidra.framework.model.DomainObject) - */ @Override - public boolean applyTo(DomainObject obj) { - SymbolTable symbolTable = ((Program) obj).getSymbolTable(); + public boolean applyTo(Program program) { + SymbolTable symbolTable = program.getSymbolTable(); try { newSymbol = symbolTable.createLabel(address, name, namespace, source); return true;//symbol already exist at this address, just complete @@ -76,17 +72,11 @@ public class AddUniqueLabelCmd implements Command { return false; } - /** - * @see ghidra.framework.cmd.Command#getStatusMsg() - */ @Override public String getStatusMsg() { return errorMsg; } - /** - * @see ghidra.framework.cmd.Command#getName() - */ @Override public String getName() { return "Add Unique Label"; diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/label/CreateNamespacesCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/label/CreateNamespacesCmd.java index 8aa1a8a83e..64c25cb3c6 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/label/CreateNamespacesCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/label/CreateNamespacesCmd.java @@ -17,7 +17,6 @@ package ghidra.app.cmd.label; import ghidra.app.util.NamespaceUtils; import ghidra.framework.cmd.Command; -import ghidra.framework.model.DomainObject; import ghidra.program.model.listing.Program; import ghidra.program.model.symbol.Namespace; import ghidra.program.model.symbol.SourceType; @@ -43,7 +42,7 @@ import ghidra.util.exception.InvalidInputException; * @since Tracker Id 619 * @see NamespaceUtils */ -public class CreateNamespacesCmd implements Command { +public class CreateNamespacesCmd implements Command { private String statusMsg; @@ -83,11 +82,12 @@ public class CreateNamespacesCmd implements Command { * @see example format * @see assumptions */ - public CreateNamespacesCmd(String namespacesString, Namespace parentNamespace, SourceType source) { + public CreateNamespacesCmd(String namespacesString, Namespace parentNamespace, + SourceType source) { if (namespacesString == null) { - throw new NullPointerException("Cannot create namespaces from a " - + "null namespacesString value."); + throw new NullPointerException( + "Cannot create namespaces from a " + "null namespacesString value."); } this.namespacesString = namespacesString; @@ -95,16 +95,12 @@ public class CreateNamespacesCmd implements Command { this.source = source; } - /** - * @see ghidra.framework.cmd.Command#applyTo(ghidra.framework.model.DomainObject) - */ @Override - public boolean applyTo(DomainObject obj) { + public boolean applyTo(Program program) { try { - leafNamespace = - NamespaceUtils.createNamespaceHierarchy(namespacesString, rootNamespace, - (Program) obj, source); + leafNamespace = NamespaceUtils.createNamespaceHierarchy(namespacesString, rootNamespace, + program, source); if (leafNamespace != null) { return true; diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/label/DeleteLabelCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/label/DeleteLabelCmd.java index b2c88faa0b..a6bcecc88c 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/label/DeleteLabelCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/label/DeleteLabelCmd.java @@ -1,6 +1,5 @@ /* ### * IP: GHIDRA - * REVIEWED: YES * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,7 +16,6 @@ package ghidra.app.cmd.label; import ghidra.framework.cmd.Command; -import ghidra.framework.model.DomainObject; import ghidra.program.model.address.Address; import ghidra.program.model.listing.Program; import ghidra.program.model.symbol.*; @@ -25,7 +23,7 @@ import ghidra.program.model.symbol.*; /** * Command to delete a label */ -public class DeleteLabelCmd implements Command { +public class DeleteLabelCmd implements Command { private Address addr; private String name; @@ -54,13 +52,9 @@ public class DeleteLabelCmd implements Command { this(addr, name, null); } - /** - * - * @see ghidra.framework.cmd.Command#applyTo(ghidra.framework.model.DomainObject) - */ @Override - public boolean applyTo(DomainObject obj) { - SymbolTable st = ((Program) obj).getSymbolTable(); + public boolean applyTo(Program program) { + SymbolTable st = program.getSymbolTable(); Symbol s = st.getSymbol(name, addr, scope); if (s == null) { errorMsg = "Symbol " + name + " not found!"; @@ -74,7 +68,7 @@ public class DeleteLabelCmd implements Command { if (s.isExternalEntryPoint() && s.isPrimary()) { if (st.getSymbols(s.getAddress()).length == 1) { externalEntryCmd = new ExternalEntryCmd(addr, false); - externalEntryCmd.applyTo(obj); + externalEntryCmd.applyTo(program); } } boolean success = st.removeSymbolSpecial(s); @@ -84,17 +78,11 @@ public class DeleteLabelCmd implements Command { return success; } - /** - * @see ghidra.framework.cmd.Command#getName() - */ @Override public String getName() { return "Delete Label"; } - /** - * @see ghidra.framework.cmd.Command#getStatusMsg() - */ @Override public String getStatusMsg() { return errorMsg; diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/label/DemanglerCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/label/DemanglerCmd.java index 0b2b592bc0..e76a9f0135 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/label/DemanglerCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/label/DemanglerCmd.java @@ -19,7 +19,6 @@ import java.util.List; import ghidra.app.util.demangler.*; import ghidra.framework.cmd.BackgroundCommand; -import ghidra.framework.model.DomainObject; import ghidra.program.model.address.Address; import ghidra.program.model.listing.Program; import ghidra.program.model.symbol.SymbolUtilities; @@ -27,7 +26,7 @@ import ghidra.util.Msg; import ghidra.util.classfinder.ClassSearcher; import ghidra.util.task.TaskMonitor; -public class DemanglerCmd extends BackgroundCommand { +public class DemanglerCmd extends BackgroundCommand { private Address addr; private String mangled; @@ -49,10 +48,9 @@ public class DemanglerCmd extends BackgroundCommand { } @Override - public boolean applyTo(DomainObject obj, TaskMonitor monitor) { + public boolean applyTo(Program prog, TaskMonitor monitor) { // search until we find a demangler that can handle the given mangled input - Program prog = (Program) obj; for (Demangler demangler : getDemanglers()) { if (!demangler.canDemangle(prog)) { continue; @@ -114,9 +112,8 @@ public class DemanglerCmd extends BackgroundCommand { return false; } - setStatusMsg( - "Failed to apply mangled symbol at " + addr + "; name: " + mangled + " (" + - demangler.getClass().getName() + "/" + demangledObject.getClass().getName() + ")"); + setStatusMsg("Failed to apply mangled symbol at " + addr + "; name: " + mangled + " (" + + demangler.getClass().getName() + "/" + demangledObject.getClass().getName() + ")"); return false; // error } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/label/ExternalEntryCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/label/ExternalEntryCmd.java index 7a9f64a201..839a731e43 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/label/ExternalEntryCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/label/ExternalEntryCmd.java @@ -1,6 +1,5 @@ /* ### * IP: GHIDRA - * REVIEWED: YES * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,7 +16,6 @@ package ghidra.app.cmd.label; import ghidra.framework.cmd.Command; -import ghidra.framework.model.DomainObject; import ghidra.program.model.address.Address; import ghidra.program.model.listing.Program; import ghidra.program.model.symbol.SymbolTable; @@ -25,12 +23,11 @@ import ghidra.program.model.symbol.SymbolTable; /** * Command for setting/unsetting an external entry point. */ -public class ExternalEntryCmd implements Command { - private SymbolTable st; +public class ExternalEntryCmd implements Command { + private Address addr; private boolean isEntry; - /** * Construct a new command for setting/unsetting an external entry point * @param addr address to set or unset as an external entry point. @@ -41,13 +38,9 @@ public class ExternalEntryCmd implements Command { this.isEntry = isEntry; } - /** - * - * @see ghidra.framework.cmd.Command#applyTo(ghidra.framework.model.DomainObject) - */ - public boolean applyTo(DomainObject obj) { - st = ((Program)obj).getSymbolTable(); - + @Override + public boolean applyTo(Program program) { + SymbolTable st = program.getSymbolTable(); if (isEntry) { st.addExternalEntryPoint(addr); } @@ -57,18 +50,12 @@ public class ExternalEntryCmd implements Command { return true; } - - - /** - * @see ghidra.framework.cmd.Command#getName() - */ + @Override public String getName() { - return "Set External" +isEntry; + return "Set External" + isEntry; } - /** - * @see ghidra.framework.cmd.Command#getStatusMsg() - */ + @Override public String getStatusMsg() { return ""; } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/label/PinSymbolCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/label/PinSymbolCmd.java index 9a404ee478..8556333728 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/label/PinSymbolCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/label/PinSymbolCmd.java @@ -16,13 +16,12 @@ package ghidra.app.cmd.label; import ghidra.framework.cmd.Command; -import ghidra.framework.model.DomainObject; import ghidra.program.model.address.Address; import ghidra.program.model.listing.Program; import ghidra.program.model.symbol.Symbol; import ghidra.program.model.symbol.SymbolTable; -public class PinSymbolCmd implements Command { +public class PinSymbolCmd implements Command { private Address addr; private String name; @@ -36,8 +35,8 @@ public class PinSymbolCmd implements Command { } @Override - public boolean applyTo(DomainObject obj) { - SymbolTable symbolTable = ((Program) obj).getSymbolTable(); + public boolean applyTo(Program program) { + SymbolTable symbolTable = program.getSymbolTable(); Symbol symbol = symbolTable.getGlobalSymbol(name, addr); if (symbol == null) { message = "Could not find symbol named " + name + " at address " + addr; diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/label/RenameLabelCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/label/RenameLabelCmd.java index c1d572571d..5c30020986 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/label/RenameLabelCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/label/RenameLabelCmd.java @@ -22,7 +22,6 @@ 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; import ghidra.program.model.listing.CircularDependencyException; import ghidra.program.model.listing.Program; @@ -34,7 +33,7 @@ import ghidra.util.exception.InvalidInputException; * Command for renaming labels. Handles converting back and forth between default and named labels * as well. */ -public class RenameLabelCmd implements Command { +public class RenameLabelCmd implements Command { private Address addr; private String oldName; @@ -123,9 +122,8 @@ public class RenameLabelCmd implements Command { } @Override - public boolean applyTo(DomainObject obj) { + public boolean applyTo(Program program) { - Program program = (Program) obj; if (currentNamespace == null) { currentNamespace = program.getGlobalNamespace(); } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/label/SetLabelNamespaceCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/label/SetLabelNamespaceCmd.java index 912560174a..714c6230fb 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/label/SetLabelNamespaceCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/label/SetLabelNamespaceCmd.java @@ -1,6 +1,5 @@ /* ### * IP: GHIDRA - * REVIEWED: YES * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,29 +16,25 @@ package ghidra.app.cmd.label; import ghidra.framework.cmd.Command; -import ghidra.framework.model.DomainObject; import ghidra.program.model.address.Address; import ghidra.program.model.listing.CircularDependencyException; import ghidra.program.model.listing.Program; import ghidra.program.model.symbol.*; -import ghidra.program.model.symbol.Symbol; -import ghidra.program.model.symbol.SymbolTable; import ghidra.util.exception.DuplicateNameException; import ghidra.util.exception.InvalidInputException; - /** * Command for changing the scope of a label. * The scope is the namespace that the label is associated with. */ -public class SetLabelNamespaceCmd implements Command { - private SymbolTable st; +public class SetLabelNamespaceCmd implements Command { + private Address addr; private String name; private Namespace oldNamespace; private Namespace newNamespace; - private String errorMsg = ""; - + private String errorMsg = ""; + /** * Constructs a new command for changing the scope of a label. * @param addr the address of the label to be changed. @@ -47,51 +42,46 @@ public class SetLabelNamespaceCmd implements Command { * @param oldNamespace the current scope of the label that will be changed. * @param newNamespace the new scope of the label. */ - public SetLabelNamespaceCmd(Address addr, String name, - Namespace oldNamespace, Namespace newNamespace) { + public SetLabelNamespaceCmd(Address addr, String name, Namespace oldNamespace, + Namespace newNamespace) { this.addr = addr; this.name = name; this.oldNamespace = oldNamespace; this.newNamespace = newNamespace; } - /** - * - * @see ghidra.framework.cmd.Command#applyTo(ghidra.framework.model.DomainObject) - */ - public boolean applyTo(DomainObject obj) { - st = ((Program)obj).getSymbolTable(); + @Override + public boolean applyTo(Program program) { + SymbolTable st = program.getSymbolTable(); Symbol s = st.getSymbol(name, addr, oldNamespace); if (s == null) { - errorMsg = "No symbol named "+name+" found at address "+addr+ - " in namespace "+oldNamespace; + errorMsg = "No symbol named " + name + " found at address " + addr + " in namespace " + + oldNamespace; return false; } try { - s.setNamespace(newNamespace); + s.setNamespace(newNamespace); return true; - }catch (DuplicateNameException e) { - errorMsg = "Symbol named "+name+" already exists in namespace "+newNamespace; - } catch (InvalidInputException e) { + } + catch (DuplicateNameException e) { + errorMsg = "Symbol named " + name + " already exists in namespace " + newNamespace; + } + catch (InvalidInputException e) { errorMsg = e.getMessage(); - } catch (CircularDependencyException e) { + } + catch (CircularDependencyException e) { errorMsg = e.getMessage(); - } + } return false; } - - /** - * @see ghidra.framework.cmd.Command#getName() - */ + @Override public String getName() { return "Set Namespace"; } - /** - * @see ghidra.framework.cmd.Command#getStatusMsg() - */ + @Override public String getStatusMsg() { return errorMsg; } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/label/SetLabelPrimaryCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/label/SetLabelPrimaryCmd.java index 1e2ca1ed75..042202224c 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/label/SetLabelPrimaryCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/label/SetLabelPrimaryCmd.java @@ -16,7 +16,6 @@ package ghidra.app.cmd.label; import ghidra.framework.cmd.Command; -import ghidra.framework.model.DomainObject; import ghidra.program.model.address.Address; import ghidra.program.model.listing.CircularDependencyException; import ghidra.program.model.listing.Program; @@ -29,8 +28,8 @@ import ghidra.util.exception.InvalidInputException; * makes sense if there is more than one label at the address - otherwise * the label will already be primary. */ -public class SetLabelPrimaryCmd implements Command { - private SymbolTable st; +public class SetLabelPrimaryCmd implements Command { + private Address addr; private String name; private Namespace namespace; @@ -50,14 +49,9 @@ public class SetLabelPrimaryCmd implements Command { this.namespace = namespace; } - /** - * - * @see ghidra.framework.cmd.Command#applyTo(ghidra.framework.model.DomainObject) - */ @Override - public boolean applyTo(DomainObject obj) { - Program program = (Program) obj; - st = program.getSymbolTable(); + public boolean applyTo(Program program) { + SymbolTable st = program.getSymbolTable(); Symbol oldSymbol = st.getPrimarySymbol(addr); if (oldSymbol == null) { @@ -75,10 +69,8 @@ public class SetLabelPrimaryCmd implements Command { // change the state of the symbol, like changing the namespace of a default symbol, // which has no effect if (!oldSymbol.isDynamic()) { - errorMsg = - "Symbol " + name + " does not exist in namespace " + namespace + - " at address " + - addr; + errorMsg = "Symbol " + name + " does not exist in namespace " + namespace + + " at address " + addr; return false; } return true; @@ -103,7 +95,8 @@ public class SetLabelPrimaryCmd implements Command { oldSymbol.setNameAndNamespace(name, namespace, symbolSource); symbol = oldSymbol; // If renamed oldSymbol is now Default source don't keep old name (handles special Thunk rename case) - if (oldSource != SourceType.DEFAULT && oldSymbol.getSource() != SourceType.DEFAULT) { + if (oldSource != SourceType.DEFAULT && + oldSymbol.getSource() != SourceType.DEFAULT) { // put the other symbol back using the old namespace and old source st.createLabel(addr, oldName, oldParent, oldSource); } @@ -127,17 +120,11 @@ public class SetLabelPrimaryCmd implements Command { return true; } - /** - * @see ghidra.framework.cmd.Command#getStatusMsg() - */ @Override public String getStatusMsg() { return errorMsg; } - /** - * @see ghidra.framework.cmd.Command#getName() - */ @Override public String getName() { return "Set Primary Label"; diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/memory/AbstractAddMemoryBlockCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/memory/AbstractAddMemoryBlockCmd.java index d98b702b44..816ae5803b 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/memory/AbstractAddMemoryBlockCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/memory/AbstractAddMemoryBlockCmd.java @@ -16,7 +16,6 @@ package ghidra.app.cmd.memory; import ghidra.framework.cmd.Command; -import ghidra.framework.model.DomainObject; import ghidra.framework.store.LockException; import ghidra.program.model.address.Address; import ghidra.program.model.address.AddressOverflowException; @@ -28,7 +27,8 @@ import ghidra.util.exception.*; /** * Base command class for adding memory blocks. */ -public abstract class AbstractAddMemoryBlockCmd implements Command { +public abstract class AbstractAddMemoryBlockCmd implements Command { + protected String message; protected final String name; protected final String comment; @@ -82,8 +82,7 @@ public abstract class AbstractAddMemoryBlockCmd implements Command { MemoryConflictException, AddressOverflowException, CancelledException; @Override - public boolean applyTo(DomainObject obj) { - Program program = (Program) obj; + public boolean applyTo(Program program) { try { Memory memory = program.getMemory(); MemoryBlock block = createMemoryBlock(memory); diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/memory/DeleteBlockCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/memory/DeleteBlockCmd.java index f942ea3521..9794d875fe 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/memory/DeleteBlockCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/memory/DeleteBlockCmd.java @@ -16,7 +16,6 @@ package ghidra.app.cmd.memory; import ghidra.framework.cmd.BackgroundCommand; -import ghidra.framework.model.DomainObject; import ghidra.framework.store.LockException; import ghidra.program.model.address.Address; import ghidra.program.model.listing.Program; @@ -29,7 +28,7 @@ import ghidra.util.task.TaskMonitor; * Command that runs in the background to delete a memory block, as * the delete may be a time consuming operation. */ -public class DeleteBlockCmd extends BackgroundCommand { +public class DeleteBlockCmd extends BackgroundCommand { private Address[] blockAddresses; private DeleteBlockListener listener; private boolean status; @@ -51,8 +50,8 @@ public class DeleteBlockCmd extends BackgroundCommand { } @Override - public boolean applyTo(DomainObject obj, TaskMonitor monitor) { - Program program = (Program) obj; + public boolean applyTo(Program program, TaskMonitor monitor) { + Memory mem = program.getMemory(); if (!program.hasExclusiveAccess()) { diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/module/AbstractModularizationCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/module/AbstractModularizationCmd.java index 61456edf5e..4566f90b84 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/module/AbstractModularizationCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/module/AbstractModularizationCmd.java @@ -19,7 +19,6 @@ import java.util.*; import java.util.function.Consumer; import ghidra.framework.cmd.BackgroundCommand; -import ghidra.framework.model.DomainObject; import ghidra.graph.GDirectedGraph; import ghidra.graph.GraphFactory; import ghidra.program.model.address.*; @@ -33,7 +32,7 @@ import ghidra.util.Msg; import ghidra.util.exception.*; import ghidra.util.task.TaskMonitor; -public abstract class AbstractModularizationCmd extends BackgroundCommand { +public abstract class AbstractModularizationCmd extends BackgroundCommand { protected Program program; private GroupPath groupPath; private String treeName; @@ -60,9 +59,9 @@ public abstract class AbstractModularizationCmd extends BackgroundCommand { protected abstract void applyModel() throws CancelledException; @Override - public boolean applyTo(DomainObject obj, TaskMonitor taskMonitor) { + public boolean applyTo(Program p, TaskMonitor taskMonitor) { - program = (Program) obj; + program = p; monitor = taskMonitor; monitor.setIndeterminate(true); ProgramModule rootModule = program.getListing().getRootModule(treeName); diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/module/CreateDefaultTreeCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/module/CreateDefaultTreeCmd.java index 7cc3ca9e14..a3c690ad2f 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/module/CreateDefaultTreeCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/module/CreateDefaultTreeCmd.java @@ -16,7 +16,6 @@ package ghidra.app.cmd.module; import ghidra.framework.cmd.Command; -import ghidra.framework.model.DomainObject; import ghidra.program.model.listing.*; import ghidra.program.model.mem.MemoryBlock; import ghidra.util.exception.DuplicateNameException; @@ -28,11 +27,11 @@ import ghidra.util.exception.DuplicateNameException; * * */ -public class CreateDefaultTreeCmd implements Command { +public class CreateDefaultTreeCmd implements Command { private String treeName; private String statusMsg; - + /** * Constructor for CreateDefaultTreeCmd. * @param treeName name of the tree to create @@ -40,24 +39,21 @@ public class CreateDefaultTreeCmd implements Command { public CreateDefaultTreeCmd(String treeName) { this.treeName = treeName; } - - /** - * - * @see ghidra.framework.cmd.Command#applyTo(ghidra.framework.model.DomainObject) - */ - public boolean applyTo(DomainObject obj) { - Program program = (Program)obj; + + @Override + public boolean applyTo(Program program) { Listing listing = program.getListing(); try { listing.createRootModule(treeName); renameFragments(program, treeName); return true; - } catch (DuplicateNameException e) { + } + catch (DuplicateNameException e) { statusMsg = e.getMessage(); } return false; } - + /** * Create a tree in the program with the given tree name. * @param program program @@ -65,9 +61,9 @@ public class CreateDefaultTreeCmd implements Command { * @return Module root module for the new tree * @throws DuplicateNameException if treeName already exists */ - static ProgramModule createRootModule(Program program, String treeName) - throws DuplicateNameException { - + static ProgramModule createRootModule(Program program, String treeName) + throws DuplicateNameException { + Listing listing = program.getListing(); ProgramModule root = listing.createRootModule(treeName); renameFragments(program, treeName); @@ -80,26 +76,23 @@ public class CreateDefaultTreeCmd implements Command { private static void renameFragments(Program program, String treeName) { Listing listing = program.getListing(); MemoryBlock[] blocks = program.getMemory().getBlocks(); - for (int i=0; i { private String name; private String statusMsg; private String parentName; private String treeName; - + /** * @param treeName name of the tree where the new Module will reside * @param name of the new Module @@ -41,22 +40,20 @@ public class CreateFolderCommand implements Command { this.parentName = parentName; } - /** - * @see ghidra.framework.cmd.Command#applyTo(ghidra.framework.model.DomainObject) - */ - public boolean applyTo(DomainObject obj) { - Program program = (Program)obj; + @Override + public boolean applyTo(Program program) { Listing listing = program.getListing(); ProgramModule m = listing.getModule(treeName, parentName); if (m == null) { statusMsg = "Folder named " + parentName + " does not exist"; return false; - } - + } + try { - m.createModule(name); + m.createModule(name); return true; - } catch (DuplicateNameException e) { + } + catch (DuplicateNameException e) { statusMsg = name + " already exists"; } return false; @@ -65,6 +62,7 @@ public class CreateFolderCommand implements Command { /** * @see ghidra.framework.cmd.Command#getStatusMsg() */ + @Override public String getStatusMsg() { return statusMsg; } @@ -72,8 +70,9 @@ public class CreateFolderCommand implements Command { /** * @see ghidra.framework.cmd.Command#getName() */ + @Override public String getName() { - return "Create Folder"; + return "Create Folder"; } } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/module/CreateFragmentCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/module/CreateFragmentCmd.java index f05c500342..ae6cc23d05 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/module/CreateFragmentCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/module/CreateFragmentCmd.java @@ -16,7 +16,6 @@ package ghidra.app.cmd.module; import ghidra.framework.cmd.Command; -import ghidra.framework.model.DomainObject; import ghidra.program.model.listing.*; import ghidra.util.exception.DuplicateNameException; @@ -25,13 +24,13 @@ import ghidra.util.exception.DuplicateNameException; * * */ -public class CreateFragmentCmd implements Command { +public class CreateFragmentCmd implements Command { private String name; private String statusMsg; - private String parentName; + private String parentName; private String treeName; - + /** * Construct a new CreateFragmentCmd. * @param treeName name of the tree where the fragment will reside @@ -50,34 +49,31 @@ public class CreateFragmentCmd implements Command { * @return false if the fragment was not created * @see ghidra.framework.cmd.Command#applyTo(ghidra.framework.model.DomainObject) */ - public boolean applyTo(DomainObject obj) { - Program program = (Program)obj; + @Override + public boolean applyTo(Program program) { Listing listing = program.getListing(); ProgramModule m = listing.getModule(treeName, parentName); if (m == null) { statusMsg = "Module named " + parentName + " does not exist"; return false; - } - + } + try { m.createFragment(name); return true; - } catch (DuplicateNameException e) { + } + catch (DuplicateNameException e) { statusMsg = name + " already exists"; } return false; } - /** - * @see ghidra.framework.cmd.Command#getStatusMsg() - */ + @Override public String getStatusMsg() { return statusMsg; } - /** - * @see ghidra.framework.cmd.Command#getName() - */ + @Override public String getName() { return "Create Fragment"; } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/module/DeleteTreeCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/module/DeleteTreeCmd.java index 4ee256bd28..3f83fe4c03 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/module/DeleteTreeCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/module/DeleteTreeCmd.java @@ -1,6 +1,5 @@ /* ### * IP: GHIDRA - * REVIEWED: YES * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,7 +16,6 @@ package ghidra.app.cmd.module; import ghidra.framework.cmd.Command; -import ghidra.framework.model.DomainObject; import ghidra.program.model.listing.Program; /** @@ -25,9 +23,9 @@ import ghidra.program.model.listing.Program; * * */ -public class DeleteTreeCmd implements Command { +public class DeleteTreeCmd implements Command { private String treeName; - + /** * Constructor for DeleteTreeCmd. * @param treeName name of tree to delete @@ -36,25 +34,17 @@ public class DeleteTreeCmd implements Command { this.treeName = treeName; } - /** - * - * @see ghidra.framework.cmd.Command#applyTo(ghidra.framework.model.DomainObject) - */ - public boolean applyTo(DomainObject obj) { - Program program = (Program)obj; + @Override + public boolean applyTo(Program program) { return program.getListing().removeTree(treeName); } - /** - * @see ghidra.framework.cmd.Command#getStatusMsg() - */ + @Override public String getStatusMsg() { return null; } - /** - * @see ghidra.framework.cmd.Command#getName() - */ + @Override public String getName() { return "Delete " + treeName; } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/module/MergeFolderCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/module/MergeFolderCmd.java index 8e5bdd464a..33964f4660 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/module/MergeFolderCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/module/MergeFolderCmd.java @@ -16,7 +16,6 @@ package ghidra.app.cmd.module; import ghidra.framework.cmd.Command; -import ghidra.framework.model.DomainObject; import ghidra.program.model.listing.*; import ghidra.util.Msg; import ghidra.util.exception.NotEmptyException; @@ -28,7 +27,7 @@ import ghidra.util.exception.NotFoundException; * * */ -public class MergeFolderCmd implements Command { +public class MergeFolderCmd implements Command { private String treeName; private String folderName; @@ -49,13 +48,9 @@ public class MergeFolderCmd implements Command { this.parentName = parentName; } - /* (non-Javadoc) - * @see ghidra.framework.cmd.Command#applyTo(ghidra.framework.model.DomainObject) - */ @Override - public boolean applyTo(DomainObject obj) { + public boolean applyTo(Program program) { - Program program = (Program) obj; Listing listing = program.getListing(); ProgramModule parentModule = listing.getModule(treeName, parentName); @@ -66,12 +61,12 @@ public class MergeFolderCmd implements Command { } Group[] groups = module.getChildren(); - for (int i = 0; i < groups.length; i++) { + for (Group group : groups) { // first check to make sure that the parent module // does not alreay contain tree group - String name = groups[i].getName(); + String name = group.getName(); ProgramModule m = listing.getModule(treeName, name); ProgramFragment f = null; try { @@ -100,8 +95,8 @@ public class MergeFolderCmd implements Command { try { ProgramModule m = listing.getModule(treeName, folderName); ProgramModule[] parents = m.getParents(); - for (int i = 0; i < parents.length; i++) { - parents[i].removeChild(folderName); + for (ProgramModule parent : parents) { + parent.removeChild(folderName); } return true; } @@ -111,17 +106,11 @@ public class MergeFolderCmd implements Command { return false; } - /* (non-Javadoc) - * @see ghidra.framework.cmd.Command#getStatusMsg() - */ @Override public String getStatusMsg() { return errMsg; } - /* (non-Javadoc) - * @see ghidra.framework.cmd.Command#getName() - */ @Override public String getName() { return "Merge " + folderName + " with Parent"; diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/module/ModuleAlgorithmCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/module/ModuleAlgorithmCmd.java index 35427dd563..e8ca28027a 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/module/ModuleAlgorithmCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/module/ModuleAlgorithmCmd.java @@ -19,7 +19,6 @@ import java.util.*; import ghidra.app.services.BlockModelService; import ghidra.framework.cmd.BackgroundCommand; -import ghidra.framework.model.DomainObject; import ghidra.framework.plugintool.PluginTool; import ghidra.program.model.address.AddressRange; import ghidra.program.model.address.AddressRangeIterator; @@ -37,11 +36,8 @@ import ghidra.util.task.TaskMonitor; * Creates a folder for each code block in the iterator. * For each code block, gets an iterator over code blocks containing the code block. * For each of these code blocks, create a fragment and move the code units to the fragment. - * - * - * */ -public class ModuleAlgorithmCmd extends BackgroundCommand { +public class ModuleAlgorithmCmd extends BackgroundCommand { private static final String NEW_MODULE_SUFFIX = " [Subroutine Tree]"; private static final String PROGRAM_CHANGED_MESSAGE = @@ -71,14 +67,9 @@ public class ModuleAlgorithmCmd extends BackgroundCommand { this.partitioningModelName = partitioningModelName; } - /** - * - * @see ghidra.framework.cmd.BackgroundCommand#applyTo(ghidra.framework.model.DomainObject, ghidra.util.task.TaskMonitor) - */ @Override - public boolean applyTo(DomainObject obj, TaskMonitor monitor) { + public boolean applyTo(Program program, TaskMonitor monitor) { - Program program = (Program) obj; ProgramModule root = program.getListing().getRootModule(treeName); try { @@ -103,13 +94,6 @@ public class ModuleAlgorithmCmd extends BackgroundCommand { this.tool = tool; } - /** - * - * @param monitor - * @throws NotFoundException - * @throws NotEmptyException - * @throws DuplicateNameException - */ private boolean applyModel(Program program, ProgramModule root, TaskMonitor monitor) throws NotFoundException, NotEmptyException, DuplicateNameException { @@ -125,9 +109,8 @@ public class ModuleAlgorithmCmd extends BackgroundCommand { (SubroutineBlockModel) blockModelService.getActiveSubroutineModel(program); } else { - partitioningModel = - (SubroutineBlockModel) blockModelService.getNewModelByName(partitioningModelName, - program); + partitioningModel = (SubroutineBlockModel) blockModelService + .getNewModelByName(partitioningModelName, program); } SubroutineBlockModel baseModel = partitioningModel.getBaseSubroutineModel(); @@ -315,6 +298,7 @@ public class ModuleAlgorithmCmd extends BackgroundCommand { module.setName(baseName + numKidsPrefix + module.getNumChildren() + "]"); } catch (DuplicateNameException e) { + // ignore } } } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/module/RenameCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/module/RenameCmd.java index a97e670b99..40afa73c87 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/module/RenameCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/module/RenameCmd.java @@ -16,7 +16,6 @@ package ghidra.app.cmd.module; import ghidra.framework.cmd.Command; -import ghidra.framework.model.DomainObject; import ghidra.program.model.listing.*; import ghidra.util.exception.DuplicateNameException; @@ -25,7 +24,7 @@ import ghidra.util.exception.DuplicateNameException; * * */ -public class RenameCmd implements Command { +public class RenameCmd implements Command { private String oldName; private String newName; @@ -34,7 +33,7 @@ public class RenameCmd implements Command { private String statusMsg; private String treeName; private boolean ignoreDuplicateName; - + /** * Construct a new RenameCmd. * @param treeName name of the tree where the module or fragment resides @@ -44,8 +43,8 @@ public class RenameCmd implements Command { * @param ignoreDuplicateName true means to ignore the exception and * don't do anything */ - public RenameCmd(String treeName, boolean isModule, - String oldName, String newName, boolean ignoreDuplicateName) { + public RenameCmd(String treeName, boolean isModule, String oldName, String newName, + boolean ignoreDuplicateName) { this.treeName = treeName; this.isModule = isModule; this.oldName = oldName; @@ -56,9 +55,9 @@ public class RenameCmd implements Command { } else { cmdName = "Rename Fragment"; - } + } } - + /** * Construct a new RenameCmd. * @param treeName name of the tree where the module or fragment resides @@ -66,35 +65,25 @@ public class RenameCmd implements Command { * @param oldName current name of the module or fragment * @param newName new name for the module or fragment */ - public RenameCmd(String treeName, boolean isModule, - String oldName, String newName) { + public RenameCmd(String treeName, boolean isModule, String oldName, String newName) { this(treeName, isModule, oldName, newName, false); } - /** - * - * @see ghidra.framework.cmd.Command#applyTo(ghidra.framework.model.DomainObject) - */ - public boolean applyTo(DomainObject obj) { - Program program = (Program)obj; - + @Override + public boolean applyTo(Program program) { return setName(program, oldName, newName); } - /** - * @see ghidra.framework.cmd.Command#getStatusMsg() - */ + @Override public String getStatusMsg() { return statusMsg; } - /** - * @see ghidra.framework.cmd.Command#getName() - */ + @Override public String getName() { return cmdName; } - + private boolean setName(Program program, String oldN, String newN) { Listing listing = program.getListing(); try { @@ -107,7 +96,8 @@ public class RenameCmd implements Command { f.setName(newN); } return true; - } catch (DuplicateNameException e) { + } + catch (DuplicateNameException e) { if (ignoreDuplicateName) { newName = oldName; return true; diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/module/RenameTreeCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/module/RenameTreeCmd.java index 0ecf4246c4..a3dfbeeb48 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/module/RenameTreeCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/module/RenameTreeCmd.java @@ -1,6 +1,5 @@ /* ### * IP: GHIDRA - * REVIEWED: YES * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,7 +16,6 @@ package ghidra.app.cmd.module; import ghidra.framework.cmd.Command; -import ghidra.framework.model.DomainObject; import ghidra.program.model.listing.Listing; import ghidra.program.model.listing.Program; import ghidra.util.exception.DuplicateNameException; @@ -29,13 +27,13 @@ import ghidra.util.exception.DuplicateNameException; * * */ -public class RenameTreeCmd implements Command { +public class RenameTreeCmd implements Command { private String oldName; private String newName; private Program program; private String statusMsg; - + /** * Constructor for RenameTreeCmd. * @param oldName old name of the tree @@ -46,31 +44,26 @@ public class RenameTreeCmd implements Command { this.newName = newName; } - /** - * - * @see ghidra.framework.cmd.Command#applyTo(ghidra.framework.model.DomainObject) - */ - public boolean applyTo(DomainObject obj) { - program = (Program)obj; + @Override + public boolean applyTo(Program p) { + program = p; Listing listing = program.getListing(); try { listing.renameTree(oldName, newName); return true; - } catch (DuplicateNameException e) { + } + catch (DuplicateNameException e) { statusMsg = e.getMessage(); } return false; } - /** - * @see ghidra.framework.cmd.Command#getStatusMsg() - */ + + @Override public String getStatusMsg() { return statusMsg; } - /** - * @see ghidra.framework.cmd.Command#getName() - */ + @Override public String getName() { return "Rename Tree View"; } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/module/ReorderModuleCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/module/ReorderModuleCmd.java index 027fb2e222..25e4586756 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/module/ReorderModuleCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/module/ReorderModuleCmd.java @@ -16,21 +16,19 @@ package ghidra.app.cmd.module; import ghidra.framework.cmd.Command; -import ghidra.framework.model.DomainObject; import ghidra.program.model.listing.*; import ghidra.util.exception.NotFoundException; /** * Command to reorder children in a module. - * - * */ -public class ReorderModuleCmd implements Command { +public class ReorderModuleCmd implements Command { private String moduleName; private String childName; private int index; - private String statusMsg; + private String statusMsg; private String treeName; + /** * Constructor for ReorderModuleCmd. * @param treeName tree that contains the parent module identified by @@ -39,41 +37,33 @@ public class ReorderModuleCmd implements Command { * @param childName name of the child to move to the new index * @param index new index for the child */ - public ReorderModuleCmd(String treeName, String parentModuleName, - String childName, int index) { + public ReorderModuleCmd(String treeName, String parentModuleName, String childName, int index) { this.treeName = treeName; moduleName = parentModuleName; this.childName = childName; this.index = index; } - /** - * - * @see ghidra.framework.cmd.Command#applyTo(ghidra.framework.model.DomainObject) - */ - public boolean applyTo(DomainObject obj) { - Program program = (Program)obj; + @Override + public boolean applyTo(Program program) { Listing listing = program.getListing(); ProgramModule m = listing.getModule(treeName, moduleName); try { m.moveChild(childName, index); return true; - } catch (NotFoundException e) { - statusMsg = e.getMessage(); + } + catch (NotFoundException e) { + statusMsg = e.getMessage(); } return false; } - /** - * @see ghidra.framework.cmd.Command#getStatusMsg() - */ + @Override public String getStatusMsg() { return statusMsg; } - /** - * @see ghidra.framework.cmd.Command#getName() - */ + @Override public String getName() { return "Reorder"; } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/module/SubroutineModelCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/module/SubroutineModelCmd.java index e6966d628f..f7eed073ce 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/module/SubroutineModelCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/module/SubroutineModelCmd.java @@ -17,7 +17,6 @@ package ghidra.app.cmd.module; import ghidra.app.services.BlockModelService; import ghidra.framework.cmd.BackgroundCommand; -import ghidra.framework.model.DomainObject; import ghidra.framework.plugintool.PluginTool; import ghidra.program.model.address.AddressRange; import ghidra.program.model.address.AddressRangeIterator; @@ -38,7 +37,7 @@ import ghidra.util.task.TaskMonitor; * * */ -public class SubroutineModelCmd extends BackgroundCommand { +public class SubroutineModelCmd extends BackgroundCommand { private static final String NEW_MODULE_SUFFIX = " [Subroutines]"; private static final String PROGRAM_CHANGED_MESSAGE = @@ -67,14 +66,8 @@ public class SubroutineModelCmd extends BackgroundCommand { this.modelName = modelName; } - /** - * - * @see ghidra.framework.cmd.BackgroundCommand#applyTo(ghidra.framework.model.DomainObject, - * ghidra.util.task.TaskMonitor) - */ @Override - public boolean applyTo(DomainObject obj, TaskMonitor monitor) { - Program program = (Program) obj; + public boolean applyTo(Program program, TaskMonitor monitor) { ProgramModule root = program.getListing().getRootModule(treeName); try { @@ -206,7 +199,7 @@ public class SubroutineModelCmd extends BackgroundCommand { * one-up number if we get a DuplicateNameException. * * @param root parent module - * @param block code block + * @param nodeName new module name * @return Fragment new fragment */ private ProgramModule createModule(ProgramModule root, String nodeName) { diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/refs/AddExternalNameCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/refs/AddExternalNameCmd.java index 278410ed22..24cc81d10b 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/refs/AddExternalNameCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/refs/AddExternalNameCmd.java @@ -1,6 +1,5 @@ /* ### * IP: GHIDRA - * REVIEWED: YES * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,9 +15,7 @@ */ package ghidra.app.cmd.refs; - import ghidra.framework.cmd.Command; -import ghidra.framework.model.DomainObject; import ghidra.program.model.listing.Program; import ghidra.program.model.symbol.SourceType; import ghidra.util.exception.DuplicateNameException; @@ -28,14 +25,13 @@ import ghidra.util.exception.InvalidInputException; * Command to update the name for an external program. * */ -public class AddExternalNameCmd implements Command { - +public class AddExternalNameCmd implements Command { private String name; private SourceType source; - + private String status; - + /** * Constructs a new command for adding the name of an external program. * @param name the new name to be used for the external program link. @@ -45,16 +41,12 @@ public class AddExternalNameCmd implements Command { this.name = name; this.source = source; if (name == null || name.length() == 0) { - throw new IllegalArgumentException("name is invalid: "+name); + throw new IllegalArgumentException("name is invalid: " + name); } } - /** - * - * @see ghidra.framework.cmd.Command#applyTo(ghidra.framework.model.DomainObject) - */ - public boolean applyTo(DomainObject obj) { - Program program = (Program)obj; + @Override + public boolean applyTo(Program program) { try { program.getExternalManager().addExternalLibraryName(name, source); return true; @@ -68,16 +60,12 @@ public class AddExternalNameCmd implements Command { return false; } - /** - * @see ghidra.framework.cmd.Command#getStatusMsg() - */ + @Override public String getStatusMsg() { return status; } - /** - * @see ghidra.framework.cmd.Command#getName() - */ + @Override public String getName() { return "Add External Program Name"; } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/refs/AddMemRefCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/refs/AddMemRefCmd.java index 04567aea53..8dcbfe29bf 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/refs/AddMemRefCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/refs/AddMemRefCmd.java @@ -1,6 +1,5 @@ /* ### * IP: GHIDRA - * REVIEWED: YES * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,15 +16,15 @@ package ghidra.app.cmd.refs; import ghidra.framework.cmd.Command; -import ghidra.framework.model.DomainObject; import ghidra.program.model.address.Address; -import ghidra.program.model.listing.*; +import ghidra.program.model.listing.CodeUnit; +import ghidra.program.model.listing.Program; import ghidra.program.model.symbol.*; /** * Command class to add a memory reference to the program. */ -public class AddMemRefCmd implements Command { +public class AddMemRefCmd implements Command { private Address fromAddr; private Address toAddr; @@ -35,85 +34,75 @@ public class AddMemRefCmd implements Command { private boolean setPrimary; /** - * Command constructor for adding a memory reference with a default refType + * Command constructor for adding a memory reference with a default refType * @param fromAddr address of the codeunit where the reference occurs * @param toAddr address of the location being referenced. * @param source the source of the reference * @param opIndex the operand index in the code unit where the reference occurs * @param setPrimary true if this reference should be primary. - */ - public AddMemRefCmd(Address fromAddr, Address toAddr, - SourceType source, int opIndex, boolean setPrimary) { - this(fromAddr, toAddr, null, source, opIndex, setPrimary); - } - - /** - * Command constructor for adding a memory reference + */ + public AddMemRefCmd(Address fromAddr, Address toAddr, SourceType source, int opIndex, + boolean setPrimary) { + this(fromAddr, toAddr, null, source, opIndex, setPrimary); + } + + /** + * Command constructor for adding a memory reference * @param fromAddr address of the codeunit where the reference occurs * @param toAddr address of the location being referenced. * @param refType reference type - how the location is being referenced. * @param source the source of the reference * @param opIndex the operand index in the code unit where the reference occurs - */ - public AddMemRefCmd(Address fromAddr, Address toAddr, RefType refType, - SourceType source, int opIndex) { - this(fromAddr, toAddr, refType, source, opIndex, false); - } + */ + public AddMemRefCmd(Address fromAddr, Address toAddr, RefType refType, SourceType source, + int opIndex) { + this(fromAddr, toAddr, refType, source, opIndex, false); + } - /** - * Command constructor for adding a memory reference + /** + * Command constructor for adding a memory reference * @param fromAddr address of the codeunit where the reference occurs * @param toAddr address of the location being referenced. * @param refType reference type - how the location is being referenced. * @param source the source of the reference * @param opIndex the operand index in the code unit where the reference occurs * @param setPrimary set the newly added reference primary - */ - public AddMemRefCmd(Address fromAddr, Address toAddr, RefType refType, - SourceType source, int opIndex, boolean setPrimary) { - this.fromAddr = fromAddr; - this.toAddr = toAddr; - this.refType = refType; - this.source = source; - this.opIndex = opIndex; - this.setPrimary = setPrimary; - } - - /** - * - * @see ghidra.framework.cmd.Command#applyTo(ghidra.framework.model.DomainObject) */ - public boolean applyTo(DomainObject obj) { - Program p = (Program)obj; - - if (refType == null) { - CodeUnit cu = p.getListing().getCodeUnitAt(fromAddr); - if (cu != null) { - refType = RefTypeFactory.getDefaultMemoryRefType(cu, opIndex, toAddr, false); - } - } - - ReferenceManager refMgr = p.getReferenceManager(); + public AddMemRefCmd(Address fromAddr, Address toAddr, RefType refType, SourceType source, + int opIndex, boolean setPrimary) { + this.fromAddr = fromAddr; + this.toAddr = toAddr; + this.refType = refType; + this.source = source; + this.opIndex = opIndex; + this.setPrimary = setPrimary; + } + + @Override + public boolean applyTo(Program program) { + if (refType == null) { + CodeUnit cu = program.getListing().getCodeUnitAt(fromAddr); + if (cu != null) { + refType = RefTypeFactory.getDefaultMemoryRefType(cu, opIndex, toAddr, false); + } + } + + ReferenceManager refMgr = program.getReferenceManager(); Reference ref = refMgr.addMemoryReference(fromAddr, toAddr, refType, source, opIndex); if (setPrimary) { refMgr.setPrimary(ref, setPrimary); } return true; - } - + } - /** - * @see ghidra.framework.cmd.Command#getStatusMsg() - */ - public String getStatusMsg() { - return ""; - } + @Override + public String getStatusMsg() { + return ""; + } - /** - * @see ghidra.framework.cmd.Command#getName() - */ - public String getName() { - return "Add Memory Reference"; - } + @Override + public String getName() { + return "Add Memory Reference"; + } } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/refs/AddMemRefsCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/refs/AddMemRefsCmd.java index dccd78812a..0d534105a8 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/refs/AddMemRefsCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/refs/AddMemRefsCmd.java @@ -1,6 +1,5 @@ /* ### * IP: GHIDRA - * REVIEWED: YES * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,7 +16,6 @@ package ghidra.app.cmd.refs; import ghidra.framework.cmd.BackgroundCommand; -import ghidra.framework.model.DomainObject; import ghidra.program.model.address.*; import ghidra.program.model.listing.*; import ghidra.program.model.symbol.*; @@ -28,7 +26,7 @@ import ghidra.util.task.TaskMonitor; * specified address and opIndex to all code units identified by a * set of addresses. */ -public class AddMemRefsCmd extends BackgroundCommand { +public class AddMemRefsCmd extends BackgroundCommand { private Address fromAddr; private AddressSetView toSet; @@ -45,8 +43,8 @@ public class AddMemRefsCmd extends BackgroundCommand { * @param source the source of the reference * @param opIndex source operand index */ - public AddMemRefsCmd(Address fromAddr, AddressSetView toSet, RefType refType, - SourceType source, int opIndex) { + public AddMemRefsCmd(Address fromAddr, AddressSetView toSet, RefType refType, SourceType source, + int opIndex) { super("Add Memory References", true, true, false); this.fromAddr = fromAddr; @@ -57,11 +55,9 @@ public class AddMemRefsCmd extends BackgroundCommand { } @Override - public boolean applyTo(DomainObject obj, TaskMonitor monitor) { - - Program p = (Program) obj; - ReferenceManager refMgr = p.getReferenceManager(); - Listing listing = p.getListing(); + public boolean applyTo(Program program, TaskMonitor monitor) { + ReferenceManager refMgr = program.getReferenceManager(); + Listing listing = program.getListing(); monitor.initialize(toSet.getNumAddresses()); monitor.setMessage("Adding memory references..."); diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/refs/AddOffsetMemRefCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/refs/AddOffsetMemRefCmd.java index e5767690ca..eaee7a9421 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/refs/AddOffsetMemRefCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/refs/AddOffsetMemRefCmd.java @@ -16,7 +16,6 @@ package ghidra.app.cmd.refs; import ghidra.framework.cmd.Command; -import ghidra.framework.model.DomainObject; import ghidra.program.model.address.Address; import ghidra.program.model.listing.Program; import ghidra.program.model.mem.MemoryBlock; @@ -25,7 +24,7 @@ import ghidra.program.model.symbol.*; /** * Command class to add an offset memory reference to the program. */ -public class AddOffsetMemRefCmd implements Command { +public class AddOffsetMemRefCmd implements Command { private Address fromAddr; private Address toAddr; @@ -34,8 +33,8 @@ public class AddOffsetMemRefCmd implements Command { private SourceType source; private int opIndex; private long offset; - - /** + + /** * Command constructor for adding an offset memory reference. The first memory reference placed on * an operand will be made primary by default. All non-memory references * will be removed from the specified operand. If toAddr corresponds to @@ -53,41 +52,32 @@ public class AddOffsetMemRefCmd implements Command { * @param offset value added to a base address to get the toAddr */ public AddOffsetMemRefCmd(Address fromAddr, Address toAddr, boolean toAddrIsBase, - RefType refType, - SourceType source, int opIndex, long offset) { - this.fromAddr = fromAddr; - this.toAddr = toAddr; + RefType refType, SourceType source, int opIndex, long offset) { + this.fromAddr = fromAddr; + this.toAddr = toAddr; this.toAddrIsBase = toAddrIsBase; - this.refType = refType; - this.source = source; - this.opIndex = opIndex; - this.offset = offset; - } - - /** - * - * @see ghidra.framework.cmd.Command#applyTo(ghidra.framework.model.DomainObject) - */ - public boolean applyTo(DomainObject obj) { - Program p = (Program)obj; - ReferenceManager refMgr = p.getReferenceManager(); + this.refType = refType; + this.source = source; + this.opIndex = opIndex; + this.offset = offset; + } + + @Override + public boolean applyTo(Program program) { + ReferenceManager refMgr = program.getReferenceManager(); refMgr.addOffsetMemReference(fromAddr, toAddr, toAddrIsBase, offset, refType, source, opIndex); return true; - } + } - /** - * @see ghidra.framework.cmd.Command#getStatusMsg() - */ - public String getStatusMsg() { - return ""; - } + @Override + public String getStatusMsg() { + return ""; + } - /** - * @see ghidra.framework.cmd.Command#getName() - */ - public String getName() { - return "Add Offset Memory Reference"; - } + @Override + public String getName() { + return "Add Offset Memory Reference"; + } } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/refs/AddRegisterRefCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/refs/AddRegisterRefCmd.java index 702ee35497..c33f959979 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/refs/AddRegisterRefCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/refs/AddRegisterRefCmd.java @@ -1,6 +1,5 @@ /* ### * IP: GHIDRA - * REVIEWED: YES * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,20 +15,19 @@ */ package ghidra.app.cmd.refs; +import java.util.List; + import ghidra.framework.cmd.Command; -import ghidra.framework.model.DomainObject; import ghidra.program.model.address.Address; import ghidra.program.model.lang.Register; import ghidra.program.model.listing.*; import ghidra.program.model.symbol.*; import ghidra.util.exception.*; -import java.util.List; - /** * Command class to add a register reference to the program. */ -public class AddRegisterRefCmd implements Command { +public class AddRegisterRefCmd implements Command { private Address fromAddr; private int opIndex; @@ -70,13 +68,8 @@ public class AddRegisterRefCmd implements Command { this.source = source; } - /** - * - * @see ghidra.framework.cmd.Command#applyTo(ghidra.framework.model.DomainObject) - */ @Override - public boolean applyTo(DomainObject obj) { - Program p = (Program) obj; + public boolean applyTo(Program p) { ReferenceManager refMgr = p.getReferenceManager(); Function f = p.getFunctionManager().getFunctionContaining(fromAddr); @@ -87,9 +80,8 @@ public class AddRegisterRefCmd implements Command { int useOffset = (int) (fromAddr.getOffset() - f.getEntryPoint().getOffset()); if (refType == null) { - refType = - RefTypeFactory.getDefaultRegisterRefType(p.getListing().getInstructionAt(fromAddr), - reg, opIndex); + refType = RefTypeFactory.getDefaultRegisterRefType( + p.getListing().getInstructionAt(fromAddr), reg, opIndex); } if (refType.isWrite()) { @@ -99,8 +91,9 @@ public class AddRegisterRefCmd implements Command { if (registers == null) { continue; } - for (Register reg : registers) { - if (rv.getRegister().contains(reg) && rv.getFirstUseOffset() == useOffset) { + for (Register r : registers) { + // determine if reference reg contains variable storage register + if (reg.contains(r) && rv.getFirstUseOffset() == useOffset) { found = true; break; } @@ -109,8 +102,8 @@ public class AddRegisterRefCmd implements Command { if (!found) { // Create a variable on write try { - Variable var = - new LocalVariableImpl(null, useOffset, null, new VariableStorage(p, reg), p); + Variable var = new LocalVariableImpl(null, useOffset, null, + new VariableStorage(p, reg), p); var = f.addLocalVariable(var, SourceType.DEFAULT); } catch (DuplicateNameException e) { @@ -127,17 +120,11 @@ public class AddRegisterRefCmd implements Command { return true; } - /** - * @see ghidra.framework.cmd.Command#getStatusMsg() - */ @Override public String getStatusMsg() { return status; } - /** - * @see ghidra.framework.cmd.Command#getName() - */ @Override public String getName() { return "Add Register Reference"; diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/refs/AddShiftedMemRefCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/refs/AddShiftedMemRefCmd.java index bad187a41b..fe88b05345 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/refs/AddShiftedMemRefCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/refs/AddShiftedMemRefCmd.java @@ -1,6 +1,5 @@ /* ### * IP: GHIDRA - * REVIEWED: YES * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,7 +16,6 @@ package ghidra.app.cmd.refs; import ghidra.framework.cmd.Command; -import ghidra.framework.model.DomainObject; import ghidra.program.model.address.Address; import ghidra.program.model.listing.Program; import ghidra.program.model.symbol.*; @@ -25,7 +23,7 @@ import ghidra.program.model.symbol.*; /** * Command class to add a shifted memory reference to the program. */ -public class AddShiftedMemRefCmd implements Command { +public class AddShiftedMemRefCmd implements Command { private Address fromAddr; private Address toAddr; @@ -33,9 +31,9 @@ public class AddShiftedMemRefCmd implements Command { private SourceType source; private int opIndex; private int shift; - - /** - * Command constructor for adding a shifted memory reference + + /** + * Command constructor for adding a shifted memory reference * @param fromAddr address of the codeunit where the reference occurs * @param toAddr computed as the value of the operand at opIndex shifted * by the number of bits specified by shiftValue @@ -43,41 +41,32 @@ public class AddShiftedMemRefCmd implements Command { * @param source the source of the reference * @param opIndex the operand index in the code unit where the reference occurs * @param shift the number of bits to shift the value by - */ - public AddShiftedMemRefCmd(Address fromAddr, Address toAddr, RefType refType, - SourceType source, int opIndex, int shift) { - this.fromAddr = fromAddr; - this.toAddr = toAddr; - this.refType = refType; - this.source = source; - this.opIndex = opIndex; - this.shift = shift; - } - - /** - * - * @see ghidra.framework.cmd.Command#applyTo(ghidra.framework.model.DomainObject) */ - public boolean applyTo(DomainObject obj) { - Program p = (Program)obj; - ReferenceManager refMgr = p.getReferenceManager(); + public AddShiftedMemRefCmd(Address fromAddr, Address toAddr, RefType refType, SourceType source, + int opIndex, int shift) { + this.fromAddr = fromAddr; + this.toAddr = toAddr; + this.refType = refType; + this.source = source; + this.opIndex = opIndex; + this.shift = shift; + } + + @Override + public boolean applyTo(Program program) { + ReferenceManager refMgr = program.getReferenceManager(); refMgr.addShiftedMemReference(fromAddr, toAddr, shift, refType, source, opIndex); return true; - } - + } - /** - * @see ghidra.framework.cmd.Command#getStatusMsg() - */ - public String getStatusMsg() { - return ""; - } + @Override + public String getStatusMsg() { + return ""; + } - /** - * @see ghidra.framework.cmd.Command#getName() - */ - public String getName() { - return "Add Shifted Memory Reference"; - } + @Override + public String getName() { + return "Add Shifted Memory Reference"; + } } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/refs/AddStackRefCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/refs/AddStackRefCmd.java index 78177407b7..2419bd7fb5 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/refs/AddStackRefCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/refs/AddStackRefCmd.java @@ -1,6 +1,5 @@ /* ### * IP: GHIDRA - * REVIEWED: YES * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,7 +16,6 @@ package ghidra.app.cmd.refs; import ghidra.framework.cmd.Command; -import ghidra.framework.model.DomainObject; import ghidra.program.model.address.Address; import ghidra.program.model.address.AddressOutOfBoundsException; import ghidra.program.model.listing.*; @@ -28,97 +26,84 @@ import ghidra.util.exception.InvalidInputException; /** * Command class for adding stack references to a program. */ -public class AddStackRefCmd implements Command { - +public class AddStackRefCmd implements Command { + private Address fromAddr; private int opIndex; private int stackOffset; private RefType refType; private SourceType source; - + private String status; - - /** - * Constructs a new command for adding a stack reference. + + /** + * Constructs a new command for adding a stack reference. * @param fromAddr "from" address within a function * @param opIndex operand index * @param stackOffset stack offset of the reference * @param source the source of this reference - */ - public AddStackRefCmd(Address fromAddr, int opIndex, int stackOffset, SourceType source) { - this.fromAddr = fromAddr; - this.opIndex = opIndex; - this.stackOffset = stackOffset; - this.source = source; - } - - /** - * Constructs a new command for adding a stack reference. + */ + public AddStackRefCmd(Address fromAddr, int opIndex, int stackOffset, SourceType source) { + this.fromAddr = fromAddr; + this.opIndex = opIndex; + this.stackOffset = stackOffset; + this.source = source; + } + + /** + * Constructs a new command for adding a stack reference. * @param fromAddr "from" address within a function * @param opIndex operand index * @param stackOffset stack offset of the reference * @param refType reference type (e.g., STACK_READ or STACK_WRITE) * @param source the source of this reference - */ - public AddStackRefCmd(Address fromAddr, int opIndex, int stackOffset, RefType refType, SourceType source) { - this.fromAddr = fromAddr; - this.opIndex = opIndex; - this.stackOffset = stackOffset; - this.refType = refType; - this.source = source; - } - - /** - * - * @see ghidra.framework.cmd.Command#applyTo(ghidra.framework.model.DomainObject) */ - public boolean applyTo(DomainObject obj) { - Program p = (Program)obj; - - Function f = p.getFunctionManager().getFunctionContaining(fromAddr); + public AddStackRefCmd(Address fromAddr, int opIndex, int stackOffset, RefType refType, + SourceType source) { + this.fromAddr = fromAddr; + this.opIndex = opIndex; + this.stackOffset = stackOffset; + this.refType = refType; + this.source = source; + } + + @Override + public boolean applyTo(Program program) { + + Function f = program.getFunctionManager().getFunctionContaining(fromAddr); if (f == null) { status = "Stack reference may only be created within a function"; return false; } - + if (refType == null) { - refType = RefTypeFactory.getDefaultStackRefType(p.getListing().getCodeUnitAt(fromAddr), opIndex); + refType = RefTypeFactory + .getDefaultStackRefType(program.getListing().getCodeUnitAt(fromAddr), opIndex); } - -// if (refType.isWrite()) { - Variable var = f.getStackFrame().getVariableContaining(stackOffset); - if (var == null) { - try { - f.getStackFrame().createVariable(null, stackOffset, null, SourceType.DEFAULT); - } - catch (DuplicateNameException e) { - } - catch (InvalidInputException e) { - status = e.getMessage(); - return false; - } - catch (AddressOutOfBoundsException e) { - status = e.getMessage(); - return false; - } -// } + + Variable var = f.getStackFrame().getVariableContaining(stackOffset); + if (var == null) { + try { + f.getStackFrame().createVariable(null, stackOffset, null, SourceType.DEFAULT); + } + catch (DuplicateNameException | InvalidInputException | AddressOutOfBoundsException e) { + status = e.getMessage(); + return false; + } } - p.getReferenceManager().addStackReference(fromAddr, opIndex, stackOffset, refType, source); + program.getReferenceManager() + .addStackReference(fromAddr, opIndex, stackOffset, refType, source); return true; - } + } - /** - * @see ghidra.framework.cmd.Command#getStatusMsg() - */ - public String getStatusMsg() { - return status; - } + @Override + public String getStatusMsg() { + return status; + } - /** - * @see ghidra.framework.cmd.Command#getName() - */ - public String getName() { - return "Add Stack Reference"; - } + @Override + public String getName() { + return "Add Stack Reference"; + } } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/refs/AssociateSymbolCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/refs/AssociateSymbolCmd.java index 84f7c145bf..c9f803bac5 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/refs/AssociateSymbolCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/refs/AssociateSymbolCmd.java @@ -1,6 +1,5 @@ /* ### * IP: GHIDRA - * REVIEWED: YES * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,14 +16,13 @@ package ghidra.app.cmd.refs; import ghidra.framework.cmd.Command; -import ghidra.framework.model.DomainObject; import ghidra.program.model.listing.Program; import ghidra.program.model.symbol.*; /** * Command class for associating a reference with a specific label */ -public class AssociateSymbolCmd implements Command { +public class AssociateSymbolCmd implements Command { private Reference ref; private String symbolName; private Namespace scope; @@ -41,55 +39,50 @@ public class AssociateSymbolCmd implements Command { this.scope = scope; symbolName = scope.getSymbol().getName(); } - /** - * Constructor + + /** + * Constructor * @param ref the reference to associate with a symbol * @param symbolName the name of the symbol with which to associate the reference. * @param scope scope of the symbol with the given symbolName - */ - public AssociateSymbolCmd(Reference ref, String symbolName, Namespace scope) { - this.ref = ref; - this.symbolName = symbolName; - this.scope = scope; - } - /** - * Create a associate symbol command for a global symbol - * @param ref - * @param symbolName - */ - public AssociateSymbolCmd(Reference ref, String symbolName) { - this(ref, symbolName, null); - } + */ + public AssociateSymbolCmd(Reference ref, String symbolName, Namespace scope) { + this.ref = ref; + this.symbolName = symbolName; + this.scope = scope; + } /** - * - * @see ghidra.framework.cmd.Command#applyTo(ghidra.framework.model.DomainObject) + * Create a associate symbol command for a global symbol + * @param ref the reference to associate with a symbol + * @param symbolName the name of the symbol with which to associate the reference. */ - public boolean applyTo(DomainObject obj) { - symTable = ((Program)obj).getSymbolTable(); - ReferenceManager refMgr = ((Program)obj).getReferenceManager(); - - Symbol s = symTable.getSymbol(symbolName, ref.getToAddress(), scope); + public AssociateSymbolCmd(Reference ref, String symbolName) { + this(ref, symbolName, null); + } + + @Override + public boolean applyTo(Program program) { + symTable = program.getSymbolTable(); + ReferenceManager refMgr = program.getReferenceManager(); + + Symbol s = symTable.getSymbol(symbolName, ref.getToAddress(), scope); if (s == null) { msg = "No symbol found for " + symbolName; return false; } refMgr.setAssociation(s, ref); return true; - } + } - /** - * @see ghidra.framework.cmd.Command#getStatusMsg() - */ - public String getStatusMsg() { - return msg; - } + @Override + public String getStatusMsg() { + return msg; + } - /** - * @see ghidra.framework.cmd.Command#getName() - */ - public String getName() { - return "Set Symbol Reference Association"; - } + @Override + public String getName() { + return "Set Symbol Reference Association"; + } } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/refs/ClearExternalNameCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/refs/ClearExternalNameCmd.java index deeb80856a..7b4df72a04 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/refs/ClearExternalNameCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/refs/ClearExternalNameCmd.java @@ -1,6 +1,5 @@ /* ### * IP: GHIDRA - * REVIEWED: YES * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,7 +16,6 @@ package ghidra.app.cmd.refs; import ghidra.framework.cmd.Command; -import ghidra.framework.model.DomainObject; import ghidra.program.model.listing.Program; import ghidra.util.exception.AssertException; import ghidra.util.exception.InvalidInputException; @@ -26,12 +24,12 @@ import ghidra.util.exception.InvalidInputException; * Command to remove an external program name from the reference manager. * */ -public class ClearExternalNameCmd implements Command { +public class ClearExternalNameCmd implements Command { private String externalName; private String status; private boolean userDefined = true; - + /** * Constructs a new command removing an external program name. * @param externalName the name of the external program name to be removed. @@ -40,30 +38,23 @@ public class ClearExternalNameCmd implements Command { this.externalName = externalName; } - /** - * - * @see ghidra.framework.cmd.Command#applyTo(ghidra.framework.model.DomainObject) - */ - public boolean applyTo(DomainObject obj) { - Program p = (Program)obj; + @Override + public boolean applyTo(Program program) { try { - p.getExternalManager().setExternalPath(externalName, null, userDefined); - } catch (InvalidInputException e) { + program.getExternalManager().setExternalPath(externalName, null, userDefined); + } + catch (InvalidInputException e) { throw new AssertException(e); } return true; } - /** - * @see ghidra.framework.cmd.Command#getStatusMsg() - */ + @Override public String getStatusMsg() { return status; } - /** - * @see ghidra.framework.cmd.Command#getName() - */ + @Override public String getName() { return "Remove External Program Name"; } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/refs/ClearFallThroughCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/refs/ClearFallThroughCmd.java index 5094813f50..fd179d6cfb 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/refs/ClearFallThroughCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/refs/ClearFallThroughCmd.java @@ -1,6 +1,5 @@ /* ### * IP: GHIDRA - * REVIEWED: YES * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,7 +16,6 @@ package ghidra.app.cmd.refs; import ghidra.framework.cmd.Command; -import ghidra.framework.model.DomainObject; import ghidra.program.model.address.Address; import ghidra.program.model.listing.Instruction; import ghidra.program.model.listing.Program; @@ -25,40 +23,31 @@ import ghidra.program.model.listing.Program; /** * Command to clear a fallthrough. */ -public class ClearFallThroughCmd implements Command { +public class ClearFallThroughCmd implements Command { Address instAddr; - /** - * Constructs a new command to remove a fallthrough. - * @param instAddr the address of the instruction from which to remove the - * fallthrough. - */ - public ClearFallThroughCmd(Address instAddr) { - this.instAddr = instAddr; - } /** - * - * @see ghidra.framework.cmd.Command#applyTo(ghidra.framework.model.DomainObject) + * Constructs a new command to remove a fallthrough. + * @param instAddr the address of the instruction from which to remove the + * fallthrough. */ - public boolean applyTo(DomainObject obj) { - Program program = (Program)obj; - Instruction inst = program.getListing().getInstructionAt(instAddr); - inst.clearFallThroughOverride(); - return true; - } + public ClearFallThroughCmd(Address instAddr) { + this.instAddr = instAddr; + } + @Override + public boolean applyTo(Program program) { + Instruction inst = program.getListing().getInstructionAt(instAddr); + inst.clearFallThroughOverride(); + return true; + } - /** - * @see ghidra.framework.cmd.Command#getName() - */ - public String getName() { - return "Clear Fall-through Override"; - } + @Override + public String getName() { + return "Clear Fall-through Override"; + } - /** - * - * @see ghidra.framework.cmd.Command#getStatusMsg() - */ + @Override public String getStatusMsg() { return null; } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/refs/EditRefTypeCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/refs/EditRefTypeCmd.java index 5ee0a4f5e7..5aa8f34506 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/refs/EditRefTypeCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/refs/EditRefTypeCmd.java @@ -1,6 +1,5 @@ /* ### * IP: GHIDRA - * REVIEWED: YES * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,50 +16,42 @@ package ghidra.app.cmd.refs; import ghidra.framework.cmd.Command; -import ghidra.framework.model.DomainObject; import ghidra.program.model.listing.Program; import ghidra.program.model.symbol.*; /** * Command to change the reference type of a memory reference */ -public class EditRefTypeCmd implements Command { +public class EditRefTypeCmd implements Command { private Reference ref; private RefType newRefType; private ReferenceManager refMgr; - /** - * Constructs a new command for changing the reference type of a reference. - * @param ref the reference whose type it to be changed. - * @param newRefType the ref type to assign to the reference. - */ - public EditRefTypeCmd(Reference ref, RefType newRefType) { - this.ref = ref; - this.newRefType = newRefType; - } /** - * - * @see ghidra.framework.cmd.Command#applyTo(ghidra.framework.model.DomainObject) + * Constructs a new command for changing the reference type of a reference. + * @param ref the reference whose type it to be changed. + * @param newRefType the ref type to assign to the reference. */ - public boolean applyTo(DomainObject obj) { - refMgr = ((Program)obj).getReferenceManager(); - ref = refMgr.updateRefType(ref, newRefType); + public EditRefTypeCmd(Reference ref, RefType newRefType) { + this.ref = ref; + this.newRefType = newRefType; + } + + @Override + public boolean applyTo(Program program) { + refMgr = program.getReferenceManager(); + ref = refMgr.updateRefType(ref, newRefType); return true; - } + } + @Override + public String getStatusMsg() { + return ""; + } - /** - * @see ghidra.framework.cmd.Command#getStatusMsg() - */ - public String getStatusMsg() { - return ""; - } - - /** - * @see ghidra.framework.cmd.Command#getName() - */ - public String getName() { - return "Edit Reference Type"; - } + @Override + public String getName() { + return "Edit Reference Type"; + } } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/refs/RemoveAllReferencesCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/refs/RemoveAllReferencesCmd.java index 41020755f8..d00a00dc16 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/refs/RemoveAllReferencesCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/refs/RemoveAllReferencesCmd.java @@ -1,6 +1,5 @@ /* ### * IP: GHIDRA - * REVIEWED: YES * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,75 +16,67 @@ package ghidra.app.cmd.refs; import ghidra.framework.cmd.Command; -import ghidra.framework.model.DomainObject; import ghidra.program.model.address.Address; import ghidra.program.model.listing.Program; -import ghidra.program.model.symbol.*; +import ghidra.program.model.symbol.Reference; +import ghidra.program.model.symbol.ReferenceManager; /** * Command to remove all references at an address or for a particular operand * index at an address. */ -public class RemoveAllReferencesCmd implements Command { +public class RemoveAllReferencesCmd implements Command { private Address fromAddr; private int opIndex; private boolean useOpIndex; - + /** - * Constructs a new command for removing all references. + * Constructs a new command for removing all references. * @param fromAddr the address of the codeunit making the reference. - */ - public RemoveAllReferencesCmd(Address fromAddr) { + */ + public RemoveAllReferencesCmd(Address fromAddr) { this.fromAddr = fromAddr; this.useOpIndex = false; - } - - /** - * Constructs a new command for removing all references. - * @param fromAddr the address of the codeunit making the reference. + } + + /** + * Constructs a new command for removing all references. + * @param fromAddr the address of the codeunit making the reference. * @param opIndex the operand index. - */ - public RemoveAllReferencesCmd(Address fromAddr, int opIndex) { + */ + public RemoveAllReferencesCmd(Address fromAddr, int opIndex) { this.fromAddr = fromAddr; this.opIndex = opIndex; this.useOpIndex = true; - } + } - /** - * - * @see ghidra.framework.cmd.Command#applyTo(ghidra.framework.model.DomainObject) - */ - public boolean applyTo(DomainObject obj) { - Program program = (Program)obj; - ReferenceManager refMgr = program.getReferenceManager(); + @Override + public boolean applyTo(Program program) { - if (!useOpIndex) { - refMgr.removeAllReferencesFrom(fromAddr); - return true; - } - - Reference[] refs = refMgr.getReferencesFrom(fromAddr, opIndex); - for (int i = 0; i < refs.length; i++) { - refMgr.delete(refs[i]); - RemoveReferenceCmd.fixupReferencedVariable(program, refs[i]); + ReferenceManager refMgr = program.getReferenceManager(); + + if (!useOpIndex) { + refMgr.removeAllReferencesFrom(fromAddr); + return true; } - return true; - } - /** - * @see ghidra.framework.cmd.Command#getStatusMsg() - */ - public String getStatusMsg() { - return null; - } + Reference[] refs = refMgr.getReferencesFrom(fromAddr, opIndex); + for (Reference ref : refs) { + refMgr.delete(ref); + RemoveReferenceCmd.fixupReferencedVariable(program, ref); + } + return true; + } - /** - * @see ghidra.framework.cmd.Command#getName() - */ - public String getName() { - return "Remove References"; - } + @Override + public String getStatusMsg() { + return null; + } + + @Override + public String getName() { + return "Remove References"; + } } - diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/refs/RemoveExternalNameCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/refs/RemoveExternalNameCmd.java index 2bb9490d63..f3f1ff8fc1 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/refs/RemoveExternalNameCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/refs/RemoveExternalNameCmd.java @@ -1,6 +1,5 @@ /* ### * IP: GHIDRA - * REVIEWED: YES * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,7 +16,6 @@ package ghidra.app.cmd.refs; import ghidra.framework.cmd.Command; -import ghidra.framework.model.DomainObject; import ghidra.program.model.listing.Program; import ghidra.program.model.symbol.ExternalManager; @@ -25,11 +23,11 @@ import ghidra.program.model.symbol.ExternalManager; * Command to remove an external program name from the reference manager. * */ -public class RemoveExternalNameCmd implements Command { +public class RemoveExternalNameCmd implements Command { private String externalName; private String status; - + /** * Constructs a new command removing an external program name. * @param externalName the name of the external program name to be removed. @@ -38,13 +36,9 @@ public class RemoveExternalNameCmd implements Command { this.externalName = externalName; } - /** - * - * @see ghidra.framework.cmd.Command#applyTo(ghidra.framework.model.DomainObject) - */ - public boolean applyTo(DomainObject obj) { - Program p = (Program)obj; - ExternalManager extMgr = p.getExternalManager(); + @Override + public boolean applyTo(Program program) { + ExternalManager extMgr = program.getExternalManager(); if (!extMgr.removeExternalLibrary(externalName)) { status = externalName + " can not be removed"; return false; @@ -52,16 +46,12 @@ public class RemoveExternalNameCmd implements Command { return true; } - /** - * @see ghidra.framework.cmd.Command#getStatusMsg() - */ + @Override public String getStatusMsg() { return status; } - /** - * @see ghidra.framework.cmd.Command#getName() - */ + @Override public String getName() { return "Remove External Program Name"; } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/refs/RemoveExternalRefCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/refs/RemoveExternalRefCmd.java index 7c5d5f30c6..87da81e97b 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/refs/RemoveExternalRefCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/refs/RemoveExternalRefCmd.java @@ -1,6 +1,5 @@ /* ### * IP: GHIDRA - * REVIEWED: YES * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,7 +16,6 @@ package ghidra.app.cmd.refs; import ghidra.framework.cmd.Command; -import ghidra.framework.model.DomainObject; import ghidra.program.model.address.Address; import ghidra.program.model.listing.Program; import ghidra.program.model.symbol.Reference; @@ -26,51 +24,43 @@ import ghidra.program.model.symbol.ReferenceManager; /** * Command for removing external references. */ -public class RemoveExternalRefCmd implements Command { +public class RemoveExternalRefCmd implements Command { private Address fromAddr; private int opIndex; - - /** - * Constructs a new command for removing an external reference. - * @param fromAddr the address of the codeunit making the external reference. - * @param opIndex the operand index. - */ - public RemoveExternalRefCmd(Address fromAddr, int opIndex) { - this.fromAddr = fromAddr; - this.opIndex = opIndex; - } /** - * - * @see ghidra.framework.cmd.Command#applyTo(ghidra.framework.model.DomainObject) + * Constructs a new command for removing an external reference. + * @param fromAddr the address of the codeunit making the external reference. + * @param opIndex the operand index. */ - public boolean applyTo(DomainObject obj) { - ReferenceManager refMgr = ((Program)obj).getReferenceManager(); - - Reference[] refs = refMgr.getReferencesFrom(fromAddr, opIndex); - for (int i = 0; i < refs.length; i++) { - Reference ref = refs[i]; + public RemoveExternalRefCmd(Address fromAddr, int opIndex) { + this.fromAddr = fromAddr; + this.opIndex = opIndex; + } + + @Override + public boolean applyTo(Program program) { + ReferenceManager refMgr = program.getReferenceManager(); + + Reference[] refs = refMgr.getReferencesFrom(fromAddr, opIndex); + for (Reference ref : refs) { if (ref.isExternalReference()) { refMgr.delete(ref); } } - return true; - } + return true; + } - /** - * @see ghidra.framework.cmd.Command#getStatusMsg() - */ - public String getStatusMsg() { - return null; - } + @Override + public String getStatusMsg() { + return null; + } - /** - * @see ghidra.framework.cmd.Command#getName() - */ - public String getName() { - return "Remove External Reference"; - } + @Override + public String getName() { + return "Remove External Reference"; + } } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/refs/RemoveReferenceCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/refs/RemoveReferenceCmd.java index 712443e779..a9a0aa983c 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/refs/RemoveReferenceCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/refs/RemoveReferenceCmd.java @@ -1,6 +1,5 @@ /* ### * IP: GHIDRA - * REVIEWED: YES * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,7 +16,6 @@ package ghidra.app.cmd.refs; import ghidra.framework.cmd.Command; -import ghidra.framework.model.DomainObject; import ghidra.program.model.address.Address; import ghidra.program.model.listing.*; import ghidra.program.model.symbol.*; @@ -25,7 +23,7 @@ import ghidra.program.model.symbol.*; /** * Command for removing memory references. */ -public class RemoveReferenceCmd implements Command { +public class RemoveReferenceCmd implements Command { private Address fromAddr; private Address toAddr; @@ -55,18 +53,13 @@ public class RemoveReferenceCmd implements Command { this.opIndex = opIndex; } - /** - * - * @see ghidra.framework.cmd.Command#applyTo(ghidra.framework.model.DomainObject) - */ @Override - public boolean applyTo(DomainObject obj) { - Program p = (Program) obj; - ReferenceManager refMgr = p.getReferenceManager(); + public boolean applyTo(Program program) { + ReferenceManager refMgr = program.getReferenceManager(); Reference ref = refMgr.getReference(fromAddr, toAddr, opIndex); if (ref != null) { refMgr.delete(ref); - fixupReferencedVariable(p, ref); + fixupReferencedVariable(program, ref); return true; } @@ -83,7 +76,7 @@ public class RemoveReferenceCmd implements Command { * to reflect the minimum reference offset within the function. * * @param p program - * @param ref reference + * @param deletedRef deleted reference */ static void fixupReferencedVariable(Program p, Reference deletedRef) { Variable var = p.getReferenceManager().getReferencedVariable(deletedRef); @@ -97,17 +90,11 @@ public class RemoveReferenceCmd implements Command { } } - /** - * @see ghidra.framework.cmd.Command#getStatusMsg() - */ @Override public String getStatusMsg() { return status; } - /** - * @see ghidra.framework.cmd.Command#getName() - */ @Override public String getName() { return "Remove Reference"; diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/refs/SetExternalNameCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/refs/SetExternalNameCmd.java index 0a2cf9fc42..8f7b8f3915 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/refs/SetExternalNameCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/refs/SetExternalNameCmd.java @@ -1,6 +1,5 @@ /* ### * IP: GHIDRA - * REVIEWED: YES * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,7 +16,6 @@ package ghidra.app.cmd.refs; import ghidra.framework.cmd.Command; -import ghidra.framework.model.DomainObject; import ghidra.program.model.listing.Program; import ghidra.util.exception.InvalidInputException; @@ -26,13 +24,13 @@ import ghidra.util.exception.InvalidInputException; * * */ -public class SetExternalNameCmd implements Command { +public class SetExternalNameCmd implements Command { private String externalName; private String externalPath; private String status; private boolean userDefined = true; - + /** * Constructs a new command for setting the external program name and path. * @param externalName the name of the link. @@ -43,32 +41,24 @@ public class SetExternalNameCmd implements Command { this.externalPath = externalPath; } - /** - * - * @see ghidra.framework.cmd.Command#applyTo(ghidra.framework.model.DomainObject) - */ - public boolean applyTo(DomainObject obj) { - Program p = (Program)obj; + @Override + public boolean applyTo(Program program) { try { - p.getExternalManager().setExternalPath(externalName, externalPath, userDefined); - } catch (InvalidInputException e) { + program.getExternalManager().setExternalPath(externalName, externalPath, userDefined); + } + catch (InvalidInputException e) { status = "Invalid name specified"; return false; } return true; } - - /** - * @see ghidra.framework.cmd.Command#getStatusMsg() - */ + @Override public String getStatusMsg() { return status; } - /** - * @see ghidra.framework.cmd.Command#getName() - */ + @Override public String getName() { return "Set External Program Name"; } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/refs/SetExternalRefCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/refs/SetExternalRefCmd.java index 61e5d670a6..5aa057cd93 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/refs/SetExternalRefCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/refs/SetExternalRefCmd.java @@ -16,7 +16,6 @@ package ghidra.app.cmd.refs; import ghidra.framework.cmd.Command; -import ghidra.framework.model.DomainObject; import ghidra.program.model.address.Address; import ghidra.program.model.listing.Program; import ghidra.program.model.symbol.*; @@ -26,7 +25,7 @@ import ghidra.util.exception.InvalidInputException; /** * Command class for adding external references. */ -public class SetExternalRefCmd implements Command { +public class SetExternalRefCmd implements Command { private Address fromAddr; private int opIndex; @@ -57,7 +56,7 @@ public class SetExternalRefCmd implements Command { this.refType = refType; this.source = source; } - + /** * Constructs a new command for adding an external reference from data using {@link RefType#DATA}. * @param fromAddr from address (source of the reference) @@ -80,9 +79,9 @@ public class SetExternalRefCmd implements Command { * @see ghidra.framework.cmd.Command#applyTo(ghidra.framework.model.DomainObject) */ @Override - public boolean applyTo(DomainObject obj) { + public boolean applyTo(Program program) { - ReferenceManager refMgr = ((Program) obj).getReferenceManager(); + ReferenceManager refMgr = program.getReferenceManager(); // Remove existing references // Reference[] refs = refMgr.getReferencesFrom(fromAddr, opIndex); @@ -104,17 +103,11 @@ public class SetExternalRefCmd implements Command { return false; } - /** - * @see ghidra.framework.cmd.Command#getStatusMsg() - */ @Override public String getStatusMsg() { return errMsg; } - /** - * @see ghidra.framework.cmd.Command#getName() - */ @Override public String getName() { return "Set External Reference"; diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/refs/SetFallThroughCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/refs/SetFallThroughCmd.java index f73d02bfcc..7b061c7ba9 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/refs/SetFallThroughCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/refs/SetFallThroughCmd.java @@ -1,6 +1,5 @@ /* ### * IP: GHIDRA - * REVIEWED: YES * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,7 +16,6 @@ package ghidra.app.cmd.refs; import ghidra.framework.cmd.Command; -import ghidra.framework.model.DomainObject; import ghidra.program.model.address.Address; import ghidra.program.model.listing.Instruction; import ghidra.program.model.listing.Program; @@ -25,42 +23,34 @@ import ghidra.program.model.listing.Program; /** * Command for setting the fallthrough property on an instruction. */ -public class SetFallThroughCmd implements Command { +public class SetFallThroughCmd implements Command { Address instAddr; Address fallthroughAddr; - /** - * Constructs a new command for setting the fallthrough property on an instruction. - * @param instAddr the address of the instruction whose fallthrought property is - * to be set. - * @param fallthroughAddr the address to use for the instructions fallthrough. - */ - public SetFallThroughCmd(Address instAddr, Address fallthroughAddr) { - this.instAddr = instAddr; - this.fallthroughAddr = fallthroughAddr; - } /** - * - * @see ghidra.framework.cmd.Command#applyTo(ghidra.framework.model.DomainObject) + * Constructs a new command for setting the fallthrough property on an instruction. + * @param instAddr the address of the instruction whose fallthrought property is + * to be set. + * @param fallthroughAddr the address to use for the instructions fallthrough. */ - public boolean applyTo(DomainObject obj) { - Program program = (Program)obj; - Instruction inst = program.getListing().getInstructionAt(instAddr); - inst.setFallThrough(fallthroughAddr); - return true; - } + public SetFallThroughCmd(Address instAddr, Address fallthroughAddr) { + this.instAddr = instAddr; + this.fallthroughAddr = fallthroughAddr; + } + @Override + public boolean applyTo(Program program) { + Instruction inst = program.getListing().getInstructionAt(instAddr); + inst.setFallThrough(fallthroughAddr); + return true; + } - /** - * @see ghidra.framework.cmd.Command#getName() - */ - public String getName() { - return "Set Fall-Through Address"; - } - /** - * - * @see ghidra.framework.cmd.Command#getStatusMsg() - */ + @Override + public String getName() { + return "Set Fall-Through Address"; + } + + @Override public String getStatusMsg() { return null; } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/refs/SetPrimaryRefCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/refs/SetPrimaryRefCmd.java index 7cc8c7d865..41e9847b86 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/refs/SetPrimaryRefCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/refs/SetPrimaryRefCmd.java @@ -1,6 +1,5 @@ /* ### * IP: GHIDRA - * REVIEWED: YES * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,7 +16,6 @@ package ghidra.app.cmd.refs; import ghidra.framework.cmd.Command; -import ghidra.framework.model.DomainObject; import ghidra.program.model.address.Address; import ghidra.program.model.listing.Program; import ghidra.program.model.symbol.Reference; @@ -27,13 +25,13 @@ import ghidra.program.model.symbol.ReferenceManager; * Command class for setting a reference to be primary. Any other * reference that was primary at that address will no longer be primary. */ -public class SetPrimaryRefCmd implements Command { +public class SetPrimaryRefCmd implements Command { private Address fromAddr; private int opIndex; private Address toAddr; private boolean isPrimary; - + private String status; /** @@ -44,7 +42,7 @@ public class SetPrimaryRefCmd implements Command { * @param isPrimary true to make the reference primary, false to make it non-primary */ public SetPrimaryRefCmd(Reference ref, boolean isPrimary) { - this (ref.getFromAddress(), ref.getOperandIndex(), ref.getToAddress(), isPrimary); + this(ref.getFromAddress(), ref.getOperandIndex(), ref.getToAddress(), isPrimary); } /** @@ -63,38 +61,30 @@ public class SetPrimaryRefCmd implements Command { this.isPrimary = isPrimary; } - /** - * - * @see ghidra.framework.cmd.Command#applyTo(ghidra.framework.model.DomainObject) - */ - public boolean applyTo(DomainObject obj) { - - ReferenceManager refMgr = ((Program)obj).getReferenceManager(); - Reference ref = refMgr.getReference(fromAddr, toAddr, opIndex); + @Override + public boolean applyTo(Program program) { - if (ref == null) { - status = "Reference not found"; - return false; - } + ReferenceManager refMgr = program.getReferenceManager(); + Reference ref = refMgr.getReference(fromAddr, toAddr, opIndex); - refMgr.setPrimary(ref, isPrimary); + if (ref == null) { + status = "Reference not found"; + return false; + } + + refMgr.setPrimary(ref, isPrimary); return true; - } + } + @Override + public String getStatusMsg() { + return status; + } - /** - * @see ghidra.framework.cmd.Command#getStatusMsg() - */ - public String getStatusMsg() { - return status; - } - - /** - * @see ghidra.framework.cmd.Command#getName() - */ - public String getName() { - return "Set Primary Reference"; - } + @Override + public String getName() { + return "Set Primary Reference"; + } } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/refs/UpdateExternalNameCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/refs/UpdateExternalNameCmd.java index f505569554..7669dc39f6 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/refs/UpdateExternalNameCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/refs/UpdateExternalNameCmd.java @@ -1,6 +1,5 @@ /* ### * IP: GHIDRA - * REVIEWED: YES * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,7 +16,6 @@ package ghidra.app.cmd.refs; import ghidra.framework.cmd.Command; -import ghidra.framework.model.DomainObject; import ghidra.program.model.listing.Program; import ghidra.program.model.symbol.SourceType; import ghidra.util.exception.DuplicateNameException; @@ -27,14 +25,14 @@ import ghidra.util.exception.InvalidInputException; * Command to update the name for an external program. * */ -public class UpdateExternalNameCmd implements Command { - +public class UpdateExternalNameCmd implements Command { + private String oldName; private String newName; private SourceType source; - + private String status; - + /** * Constructs a new command for updating the name of an external program. * @param oldName the current name of the external program link. @@ -50,33 +48,27 @@ public class UpdateExternalNameCmd implements Command { } } - /** - * - * @see ghidra.framework.cmd.Command#applyTo(ghidra.framework.model.DomainObject) - */ - public boolean applyTo(DomainObject obj) { - Program program = (Program)obj; + @Override + public boolean applyTo(Program program) { try { program.getExternalManager().updateExternalLibraryName(oldName, newName, source); return true; - } catch (DuplicateNameException e) { + } + catch (DuplicateNameException e) { status = newName + " already exists"; - } catch (InvalidInputException e) { + } + catch (InvalidInputException e) { status = e.getMessage(); } return false; } - /** - * @see ghidra.framework.cmd.Command#getStatusMsg() - */ + @Override public String getStatusMsg() { return status; } - /** - * @see ghidra.framework.cmd.Command#getName() - */ + @Override public String getName() { return "Update External Program Name"; } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/register/SetRegisterCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/register/SetRegisterCmd.java index 4632bc7654..658a0ad541 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/register/SetRegisterCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/register/SetRegisterCmd.java @@ -1,6 +1,5 @@ /* ### * IP: GHIDRA - * REVIEWED: YES * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,19 +15,18 @@ */ package ghidra.app.cmd.register; +import java.math.BigInteger; + import ghidra.framework.cmd.Command; -import ghidra.framework.model.DomainObject; import ghidra.program.model.address.Address; import ghidra.program.model.lang.Register; import ghidra.program.model.listing.*; import ghidra.util.Msg; -import java.math.BigInteger; - /** * Command for setting the value of a register over a range of addresses. */ -public class SetRegisterCmd implements Command { +public class SetRegisterCmd implements Command { private Register register; private Address start; private Address end; @@ -55,12 +53,9 @@ public class SetRegisterCmd implements Command { this.value = value; } - /** - * @see ghidra.framework.cmd.Command#applyTo(ghidra.framework.model.DomainObject) - */ @Override - public boolean applyTo(DomainObject obj) { - Program program = (Program) obj; + public boolean applyTo(Program program) { + ProgramContext context = program.getProgramContext(); try { @@ -74,17 +69,11 @@ public class SetRegisterCmd implements Command { return true; } - /** - * @see ghidra.framework.cmd.Command#getStatusMsg() - */ @Override public String getStatusMsg() { return errorMsg; } - /** - * @see ghidra.framework.cmd.Command#getName() - */ @Override public String getName() { return "Set Register Value"; diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/merge/DataTypeArchiveMergeManager.java b/Ghidra/Features/Base/src/main/java/ghidra/app/merge/DataTypeArchiveMergeManager.java index cc3d2c8ee4..d751da4055 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/merge/DataTypeArchiveMergeManager.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/merge/DataTypeArchiveMergeManager.java @@ -1,6 +1,5 @@ /* ### * IP: GHIDRA - * REVIEWED: YES * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,7 +16,7 @@ package ghidra.app.merge; import ghidra.app.merge.datatypes.DataTypeMergeManager; -import ghidra.framework.model.UndoableDomainObject; +import ghidra.framework.model.DomainObject; import ghidra.framework.plugintool.ModalPluginTool; import ghidra.program.model.data.DataTypeManagerDomainObject; import ghidra.program.model.listing.DataTypeArchive; @@ -27,15 +26,14 @@ import ghidra.program.model.listing.DataTypeArchiveChangeSet; * Top level object that manages each step of the merge/resolve conflicts * process. */ -public class DataTypeArchiveMergeManager extends MergeManager { +public class DataTypeArchiveMergeManager extends MergeManager { - public DataTypeArchiveMergeManager( DataTypeManagerDomainObject resultDtArchive, - DataTypeManagerDomainObject myDtArchive, - DataTypeManagerDomainObject originalDtArchive, - DataTypeManagerDomainObject latestDtArchive, - DataTypeArchiveChangeSet latestChangeSet, - DataTypeArchiveChangeSet myChangeSet) { - super(resultDtArchive, myDtArchive, originalDtArchive, latestDtArchive, latestChangeSet, myChangeSet); + public DataTypeArchiveMergeManager(DataTypeManagerDomainObject resultDtArchive, + DataTypeManagerDomainObject myDtArchive, DataTypeManagerDomainObject originalDtArchive, + DataTypeManagerDomainObject latestDtArchive, DataTypeArchiveChangeSet latestChangeSet, + DataTypeArchiveChangeSet myChangeSet) { + super(resultDtArchive, myDtArchive, originalDtArchive, latestDtArchive, latestChangeSet, + myChangeSet); } @Override @@ -43,14 +41,13 @@ public class DataTypeArchiveMergeManager extends MergeManager { // create the merge resolvers int idx = 0; mergeResolvers = new MergeResolver[1]; - - mergeResolvers[idx++] = new DataTypeMergeManager( this, - (DataTypeManagerDomainObject)resultDomainObject, - (DataTypeManagerDomainObject)myDomainObject, - (DataTypeManagerDomainObject)originalDomainObject, - (DataTypeManagerDomainObject)latestDomainObject, - (DataTypeArchiveChangeSet)latestChangeSet, - (DataTypeArchiveChangeSet)myChangeSet); + + mergeResolvers[idx++] = + new DataTypeMergeManager(this, (DataTypeManagerDomainObject) resultDomainObject, + (DataTypeManagerDomainObject) myDomainObject, + (DataTypeManagerDomainObject) originalDomainObject, + (DataTypeManagerDomainObject) latestDomainObject, + (DataTypeArchiveChangeSet) latestChangeSet, (DataTypeArchiveChangeSet) myChangeSet); } /** @@ -64,23 +61,23 @@ public class DataTypeArchiveMergeManager extends MergeManager { public DataTypeArchive getDataTypeArchive(int version) { switch (version) { case MergeConstants.LATEST: - return (DataTypeArchive)latestDomainObject; + return (DataTypeArchive) latestDomainObject; case MergeConstants.MY: - return (DataTypeArchive)myDomainObject; + return (DataTypeArchive) myDomainObject; case MergeConstants.ORIGINAL: - return (DataTypeArchive)originalDomainObject; + return (DataTypeArchive) originalDomainObject; case MergeConstants.RESULT: - return (DataTypeArchive)resultDomainObject; + return (DataTypeArchive) resultDomainObject; default: return null; } } - + @Override protected MergeManagerPlugin createMergeManagerPlugin(ModalPluginTool mergePluginTool, - MergeManager multiUserMergeManager, UndoableDomainObject modifiableDomainObject) { - return new DataTypeArchiveMergeManagerPlugin(mergeTool, DataTypeArchiveMergeManager.this, - (DataTypeArchive)resultDomainObject); + MergeManager multiUserMergeManager, DomainObject modifiableDomainObject) { + return new DataTypeArchiveMergeManagerPlugin(mergeTool, DataTypeArchiveMergeManager.this, + (DataTypeArchive) resultDomainObject); } @Override diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/merge/MergeManager.java b/Ghidra/Features/Base/src/main/java/ghidra/app/merge/MergeManager.java index 8edab3c4ad..8bba154e40 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/merge/MergeManager.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/merge/MergeManager.java @@ -25,7 +25,7 @@ import javax.swing.SwingUtilities; import generic.util.WindowUtilities; import ghidra.framework.data.DomainObjectMergeManager; import ghidra.framework.model.DomainFile; -import ghidra.framework.model.UndoableDomainObject; +import ghidra.framework.model.DomainObject; import ghidra.framework.plugintool.*; import ghidra.framework.plugintool.util.PluginException; import ghidra.program.model.listing.DomainObjectChangeSet; @@ -43,10 +43,10 @@ public abstract class MergeManager implements DomainObjectMergeManager { protected MergeResolver[] mergeResolvers; - protected UndoableDomainObject resultDomainObject; // where changes will be merged to - protected UndoableDomainObject myDomainObject; // source of changes to be applied - protected UndoableDomainObject originalDomainObject; // original version that was checked out - protected UndoableDomainObject latestDomainObject; // latest version of the program + protected DomainObject resultDomainObject; // where changes will be merged to + protected DomainObject myDomainObject; // source of changes to be applied + protected DomainObject originalDomainObject; // original version that was checked out + protected DomainObject latestDomainObject; // latest version of the program protected DomainObjectChangeSet latestChangeSet; protected DomainObjectChangeSet myChangeSet; @@ -69,10 +69,9 @@ public abstract class MergeManager implements DomainObjectMergeManager { // protected boolean isShowingListingMergePanel = false; - public MergeManager(UndoableDomainObject resultDomainObject, - UndoableDomainObject myDomainObject, UndoableDomainObject originalDomainObject, - UndoableDomainObject latestDomainObject, DomainObjectChangeSet latestChangeSet, - DomainObjectChangeSet myChangeSet) { + public MergeManager(DomainObject resultDomainObject, DomainObject myDomainObject, + DomainObject originalDomainObject, DomainObject latestDomainObject, + DomainObjectChangeSet latestChangeSet, DomainObjectChangeSet myChangeSet) { this.resultDomainObject = resultDomainObject; this.myDomainObject = myDomainObject; this.originalDomainObject = originalDomainObject; @@ -96,7 +95,7 @@ public abstract class MergeManager implements DomainObjectMergeManager { * @return the indicated program version or null if a valid version isn't specified. * @see MergeConstants */ - public UndoableDomainObject getDomainObject(int version) { + public DomainObject getDomainObject(int version) { switch (version) { case MergeConstants.LATEST: return latestDomainObject; @@ -209,7 +208,7 @@ public abstract class MergeManager implements DomainObjectMergeManager { } protected abstract MergeManagerPlugin createMergeManagerPlugin(ModalPluginTool mergePluginTool, - MergeManager multiUserMergeManager, UndoableDomainObject modifiableDomainObject); + MergeManager multiUserMergeManager, DomainObject modifiableDomainObject); protected abstract void initializeMerge(); @@ -559,7 +558,7 @@ public abstract class MergeManager implements DomainObjectMergeManager { * @param infoType the string indicating the type of resolve information * @param infoObject the object for the named string. This information is * determined by the merge manager that creates it. - * @see getResolveInformation(String) + * @see #getResolveInformation(String) */ @Override public void setResolveInformation(String infoType, Object infoObject) { diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/merge/MergeManagerPlugin.java b/Ghidra/Features/Base/src/main/java/ghidra/app/merge/MergeManagerPlugin.java index 7843ed85e2..a1be258766 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/merge/MergeManagerPlugin.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/merge/MergeManagerPlugin.java @@ -33,7 +33,7 @@ public abstract class MergeManagerPlugin extends Plugin protected MergeManager mergeManager; protected MergeManagerProvider provider; - protected UndoableDomainObject currentDomainObject; + protected DomainObject currentDomainObject; /** * Constructor for plugin that handles multi-user merge of programs. @@ -42,7 +42,7 @@ public abstract class MergeManagerPlugin extends Plugin * @param domainObject the current domain object */ public MergeManagerPlugin(PluginTool tool, MergeManager mergeManager, - UndoableDomainObject domainObject) { + DomainObject domainObject) { super(tool); this.mergeManager = mergeManager; this.currentDomainObject = domainObject; @@ -210,26 +210,26 @@ public abstract class MergeManagerPlugin extends Plugin return false; } - public boolean closeDomainObject(UndoableDomainObject domainObject, boolean ignoreChanges) { + public boolean closeDomainObject(DomainObject domainObject, boolean ignoreChanges) { return false; } - public UndoableDomainObject[] getAllOpenDomainObjects() { - return new UndoableDomainObject[] { mergeManager.getDomainObject(MergeConstants.RESULT), + public DomainObject[] getAllOpenDomainObjects() { + return new DomainObject[] { mergeManager.getDomainObject(MergeConstants.RESULT), mergeManager.getDomainObject(MergeConstants.LATEST), mergeManager.getDomainObject(MergeConstants.MY), mergeManager.getDomainObject(MergeConstants.ORIGINAL) }; } - public UndoableDomainObject getCurrentDomainObject() { + public DomainObject getCurrentDomainObject() { return currentDomainObject; } - public int getSearchPriority(UndoableDomainObject domainObject) { + public int getSearchPriority(DomainObject domainObject) { return 0; } - public boolean isVisible(UndoableDomainObject domainObject) { + public boolean isVisible(DomainObject domainObject) { return false; } @@ -245,26 +245,26 @@ public abstract class MergeManagerPlugin extends Plugin return null; } - public void openDomainObject(UndoableDomainObject domainObject) { + public void openDomainObject(DomainObject domainObject) { } - public void openDomainObject(UndoableDomainObject domainObject, boolean current) { + public void openDomainObject(DomainObject domainObject, boolean current) { } - public void openDomainObject(UndoableDomainObject domainObject, int state) { + public void openDomainObject(DomainObject domainObject, int state) { } - public void releaseDomainObject(UndoableDomainObject domainObject, Object persistentOwner) { + public void releaseDomainObject(DomainObject domainObject, Object persistentOwner) { } - public void setCurrentDomainObject(UndoableDomainObject domainObject) { + public void setCurrentDomainObject(DomainObject domainObject) { } - public boolean setPersistentOwner(UndoableDomainObject domainObject, Object owner) { + public boolean setPersistentOwner(DomainObject domainObject, Object owner) { return false; } - public void setSearchPriority(UndoableDomainObject domainObject, int priority) { + public void setSearchPriority(DomainObject domainObject, int priority) { } } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/merge/ProgramMultiUserMergeManager.java b/Ghidra/Features/Base/src/main/java/ghidra/app/merge/ProgramMultiUserMergeManager.java index 6f18ff7fcd..3dc78f7f0d 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/merge/ProgramMultiUserMergeManager.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/merge/ProgramMultiUserMergeManager.java @@ -31,7 +31,7 @@ import ghidra.app.nav.*; import ghidra.app.plugin.core.navigation.GoToAddressLabelPlugin; import ghidra.app.util.ListingHighlightProvider; import ghidra.app.util.viewer.util.FieldNavigator; -import ghidra.framework.model.UndoableDomainObject; +import ghidra.framework.model.DomainObject; import ghidra.framework.plugintool.ModalPluginTool; import ghidra.framework.plugintool.Plugin; import ghidra.framework.plugintool.util.PluginException; @@ -140,7 +140,7 @@ public class ProgramMultiUserMergeManager extends MergeManager { @Override protected MergeManagerPlugin createMergeManagerPlugin(ModalPluginTool mergePluginTool, - MergeManager multiUserMergeManager, UndoableDomainObject modifiableDomainObject) { + MergeManager multiUserMergeManager, DomainObject modifiableDomainObject) { return new ProgramMergeManagerPlugin(mergeTool, ProgramMultiUserMergeManager.this, (Program) resultDomainObject); } @@ -516,7 +516,8 @@ class MergeNavigatable implements Navigatable { } @Override - public void removeHighlightProvider(ListingHighlightProvider highlightProvider, Program program) { + public void removeHighlightProvider(ListingHighlightProvider highlightProvider, + Program program) { // currently unsupported } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/analysis/AnalysisBackgroundCommand.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/analysis/AnalysisBackgroundCommand.java index 887526c3c8..f74dc26dfe 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/analysis/AnalysisBackgroundCommand.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/analysis/AnalysisBackgroundCommand.java @@ -21,7 +21,6 @@ package ghidra.app.plugin.core.analysis; import ghidra.framework.cmd.MergeableBackgroundCommand; -import ghidra.framework.model.DomainObject; import ghidra.program.model.listing.Program; import ghidra.program.util.GhidraProgramUtilities; import ghidra.util.SystemUtilities; @@ -30,11 +29,9 @@ import ghidra.util.task.TaskMonitor; /** * Background task to artificially kick off Auto analysis by * calling anything that analyzes bytes. - * - * - * */ -public class AnalysisBackgroundCommand extends MergeableBackgroundCommand { +public class AnalysisBackgroundCommand extends MergeableBackgroundCommand { + private AutoAnalysisManager mgr; private boolean markAsAnalyzed; @@ -51,17 +48,17 @@ public class AnalysisBackgroundCommand extends MergeableBackgroundCommand { } @Override - public boolean applyTo(DomainObject obj, TaskMonitor monitor) { + public boolean applyTo(Program program, TaskMonitor monitor) { if (markAsAnalyzed) { - GhidraProgramUtilities.markProgramAnalyzed((Program) obj); + GhidraProgramUtilities.markProgramAnalyzed(program); } mgr.startAnalysis(monitor); return true; } - /** Merges the properties of the two commands */ @Override - public MergeableBackgroundCommand mergeCommands(MergeableBackgroundCommand command) { + public MergeableBackgroundCommand mergeCommands( + MergeableBackgroundCommand command) { SystemUtilities.assertTrue(command instanceof AnalysisBackgroundCommand, "This code assumes that the " + "two commands are both AnalysisBackgroundCommands and this is not the case."); diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/analysis/AnalysisTask.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/analysis/AnalysisTask.java index 4a07f1b965..6581afa65c 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/analysis/AnalysisTask.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/analysis/AnalysisTask.java @@ -1,6 +1,5 @@ /* ### * IP: GHIDRA - * REVIEWED: YES * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,12 +17,11 @@ package ghidra.app.plugin.core.analysis; import ghidra.app.util.importer.MessageLog; import ghidra.framework.cmd.BackgroundCommand; -import ghidra.framework.model.DomainObject; import ghidra.program.model.listing.Program; import ghidra.util.exception.CancelledException; import ghidra.util.task.TaskMonitor; -public class AnalysisTask extends BackgroundCommand { +public class AnalysisTask extends BackgroundCommand { AnalysisScheduler scheduler; private MessageLog log; @@ -34,9 +32,9 @@ public class AnalysisTask extends BackgroundCommand { } @Override - public boolean applyTo(DomainObject obj, TaskMonitor monitor) { + public boolean applyTo(Program program, TaskMonitor monitor) { try { - return scheduler.runAnalyzer((Program) obj, monitor, log); + return scheduler.runAnalyzer(program, monitor, log); } catch (CancelledException e) { return false; diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/analysis/AnalyzeAllOpenProgramsTask.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/analysis/AnalyzeAllOpenProgramsTask.java index 76bad7aaad..cd9ecdb3c0 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/analysis/AnalyzeAllOpenProgramsTask.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/analysis/AnalyzeAllOpenProgramsTask.java @@ -28,7 +28,6 @@ import docking.widgets.label.GLabel; import generic.theme.GThemeDefaults.Colors.Palette; import ghidra.GhidraOptions; import ghidra.app.services.ProgramManager; -import ghidra.framework.model.DomainObject; import ghidra.framework.options.Options; import ghidra.framework.plugintool.Plugin; import ghidra.framework.plugintool.PluginTool; @@ -363,13 +362,13 @@ class AnalyzeAllOpenProgramsTask extends Task { } @Override - public boolean applyTo(DomainObject obj, TaskMonitor monitor) { + public boolean applyTo(Program program, TaskMonitor monitor) { monitor.addCancelledListener(bottomUpCancelledListener); // note: this call has to be here, so our listener on the monitor is in place manager.reAnalyzeAll(null); - boolean result = super.applyTo(obj, monitor); + boolean result = super.applyTo(program, monitor); monitor.removeCancelledListener(bottomUpCancelledListener); finishedLatch.countDown(); return result; diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/analysis/GolangSymbolAnalyzer.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/analysis/GolangSymbolAnalyzer.java index 032ae5d25c..50d35f7b68 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/analysis/GolangSymbolAnalyzer.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/analysis/GolangSymbolAnalyzer.java @@ -40,7 +40,6 @@ import ghidra.app.util.bin.format.golang.structmapping.MarkupSession; import ghidra.app.util.importer.MessageLog; import ghidra.app.util.viewer.field.AddressAnnotatedStringHandler; import ghidra.framework.cmd.BackgroundCommand; -import ghidra.framework.model.DomainObject; import ghidra.framework.options.Options; import ghidra.program.model.address.*; import ghidra.program.model.data.*; @@ -503,7 +502,8 @@ public class GolangSymbolAnalyzer extends AbstractAnalyzer { * main entry point of the duff function to any unnamed functions that are within the footprint * of the main function. */ - private static class FixupDuffAlternateEntryPointsBackgroundCommand extends BackgroundCommand { + private static class FixupDuffAlternateEntryPointsBackgroundCommand + extends BackgroundCommand { private Function duffFunc; private GoFuncData funcData; @@ -515,11 +515,13 @@ public class GolangSymbolAnalyzer extends AbstractAnalyzer { } @Override - public boolean applyTo(DomainObject obj, TaskMonitor monitor) { + public boolean applyTo(Program program, TaskMonitor monitor) { + if (!duffFunc.getProgram().equals(program)) { + throw new AssertionError(); + } String ccName = duffFunc.getCallingConventionName(); Namespace funcNS = duffFunc.getParentNamespace(); AddressSet funcBody = new AddressSet(funcData.getBody()); - Program program = duffFunc.getProgram(); String duffComment = program.getListing() .getCodeUnitAt(duffFunc.getEntryPoint()) .getComment(CodeUnit.PLATE_COMMENT); @@ -558,7 +560,7 @@ public class GolangSymbolAnalyzer extends AbstractAnalyzer { * overrides to callsites that have a RTTI type parameter that return a specialized * type instead of a void*. */ - private static class PropagateRttiBackgroundCommand extends BackgroundCommand { + private static class PropagateRttiBackgroundCommand extends BackgroundCommand { record RttiFuncInfo(GoSymbolName funcName, int rttiParamIndex, java.util.function.Function returnTypeMapper) { @@ -584,7 +586,7 @@ public class GolangSymbolAnalyzer extends AbstractAnalyzer { } @Override - public boolean applyTo(DomainObject obj, TaskMonitor monitor) { + public boolean applyTo(Program program, TaskMonitor monitor) { if (goBinary.newStorageAllocator().isAbi0Mode()) { // If abi0 mode, don't even bother because currently only handles rtti passed via // register. diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/analysis/OneShotAnalysisCommand.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/analysis/OneShotAnalysisCommand.java index 7bd1ac35fb..fc439e5369 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/analysis/OneShotAnalysisCommand.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/analysis/OneShotAnalysisCommand.java @@ -18,7 +18,6 @@ package ghidra.app.plugin.core.analysis; import ghidra.app.services.Analyzer; import ghidra.app.util.importer.MessageLog; import ghidra.framework.cmd.BackgroundCommand; -import ghidra.framework.model.DomainObject; import ghidra.program.model.address.AddressSetView; import ghidra.program.model.listing.Program; import ghidra.util.exception.CancelledException; @@ -28,7 +27,7 @@ import ghidra.util.task.TaskMonitor; * Background task to artificially kick off Auto analysis by * calling anything that analyzes bytes. */ -public class OneShotAnalysisCommand extends BackgroundCommand { +public class OneShotAnalysisCommand extends BackgroundCommand { private Analyzer analyzer; private AddressSetView set; private MessageLog log; @@ -41,8 +40,7 @@ public class OneShotAnalysisCommand extends BackgroundCommand { } @Override - public boolean applyTo(DomainObject obj, TaskMonitor monitor) { - Program program = (Program) obj; + public boolean applyTo(Program program, TaskMonitor monitor) { try { monitor.setMessage(analyzer.getName()); return analyzer.added(program, set, monitor, log); diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/analysis/OperandReferenceAnalyzer.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/analysis/OperandReferenceAnalyzer.java index c5baa55b4e..8bc268083f 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/analysis/OperandReferenceAnalyzer.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/analysis/OperandReferenceAnalyzer.java @@ -31,7 +31,8 @@ import ghidra.app.services.*; import ghidra.app.util.PseudoDisassembler; import ghidra.app.util.importer.MessageLog; import ghidra.app.util.opinion.PeLoader; -import ghidra.framework.cmd.*; +import ghidra.framework.cmd.BackgroundCommand; +import ghidra.framework.cmd.CompoundBackgroundCommand; import ghidra.framework.options.Options; import ghidra.program.disassemble.Disassembler; import ghidra.program.model.address.*; @@ -145,7 +146,7 @@ public class OperandReferenceAnalyzer extends AbstractAnalyzer { pointerEnabled = false; addressTablesEnabled = false; } - + boolean isArm = program.getLanguage() .getProcessor() .equals(Processor.findOrPossiblyCreateProcessor("ARM")); @@ -155,7 +156,7 @@ public class OperandReferenceAnalyzer extends AbstractAnalyzer { pointerEnabled = false; addressTablesEnabled = false; } - + // only analyze programs with address spaces > 16 bits int bitSize = defaultAddressSpace.getSize(); return bitSize > 16; @@ -499,7 +500,8 @@ public class OperandReferenceAnalyzer extends AbstractAnalyzer { // TODO: delayed disassembly should check if the code starts are still valid AddressSet doDisTargets = disTargets.subtract(doneDisSet); if (!doDisTargets.isEmpty()) { - BackgroundCommand cmd = createDisassemblyCommandsForAddress(program, doDisTargets); + BackgroundCommand cmd = + createDisassemblyCommandsForAddress(program, doDisTargets); mgr.schedule(cmd, AnalysisPriority.REFERENCE_ANALYSIS.after().after().priority()); } @@ -509,8 +511,8 @@ public class OperandReferenceAnalyzer extends AbstractAnalyzer { while (foundIter.hasNext()) { Address target = foundIter.next(); program.getBookmarkManager() - .setBookmark(target, BookmarkType.ANALYSIS, - "Found Code", "Found code from operand reference"); + .setBookmark(target, BookmarkType.ANALYSIS, "Found Code", + "Found code from operand reference"); } } @@ -523,10 +525,10 @@ public class OperandReferenceAnalyzer extends AbstractAnalyzer { return true; } - private CompoundBackgroundCommand createDisassemblyCommandsForAddress(Program program, + private CompoundBackgroundCommand createDisassemblyCommandsForAddress(Program program, AddressSet locations) { - CompoundBackgroundCommand backCmd = - new CompoundBackgroundCommand("Subroutine References", false, true); + CompoundBackgroundCommand backCmd = + new CompoundBackgroundCommand<>("Subroutine References", false, true); Listing listing = program.getListing(); int align = program.getLanguage().getInstructionAlignment(); @@ -595,8 +597,8 @@ public class OperandReferenceAnalyzer extends AbstractAnalyzer { // Get rid of any bad disassembly bookmark AddressSet set = new AddressSet(toAddr); program.getBookmarkManager() - .removeBookmarks(set, BookmarkType.ERROR, - Disassembler.ERROR_BOOKMARK_CATEGORY, monitor); + .removeBookmarks(set, BookmarkType.ERROR, Disassembler.ERROR_BOOKMARK_CATEGORY, + monitor); } // make sure function created at destination @@ -657,8 +659,8 @@ public class OperandReferenceAnalyzer extends AbstractAnalyzer { // then the target becomes the output varnode Varnode[] inputs = element.getInputs(); for (Varnode input : inputs) { - if ((target != null && target.equals(input)) || (input.isConstant() && - input.getOffset() == targetValue.getUnsignedOffset())) { + if ((target != null && target.equals(input)) || + (input.isConstant() && input.getOffset() == targetValue.getUnsignedOffset())) { if (op == PcodeOp.LOAD || op == PcodeOp.STORE) { continue; } @@ -782,9 +784,8 @@ public class OperandReferenceAnalyzer extends AbstractAnalyzer { if (lastGoodTable != null) { instr.removeOperandReference(opIndex, target); program.getReferenceManager() - .addOffsetMemReference(instr.getMinAddress(), - lastGoodTable.getTopAddress(), false, -((i + 3) * entryLen), - RefType.DATA, SourceType.ANALYSIS, opIndex); + .addOffsetMemReference(instr.getMinAddress(), lastGoodTable.getTopAddress(), + false, -((i + 3) * entryLen), RefType.DATA, SourceType.ANALYSIS, opIndex); } return lastGoodTable; @@ -842,7 +843,7 @@ public class OperandReferenceAnalyzer extends AbstractAnalyzer { // check if it could be code if (!isValidInstruction(pdis, target)) { if (clearAllUndefined(program, target, asciiLen)) { - Command cmd = new CreateStringCmd(target, asciiLen, false); + CreateStringCmd cmd = new CreateStringCmd(target, asciiLen, false); cmd.applyTo(program); } } @@ -869,7 +870,7 @@ public class OperandReferenceAnalyzer extends AbstractAnalyzer { // check if it could be code if (!isValidInstruction(pdis, target)) { if (clearAllUndefined(program, target, uniLen)) { - Command cmd = new CreateStringCmd(target, 2 * (uniLen + 1), true); + CreateStringCmd cmd = new CreateStringCmd(target, 2 * (uniLen + 1), true); cmd.applyTo(program); } } @@ -879,13 +880,15 @@ public class OperandReferenceAnalyzer extends AbstractAnalyzer { } /** - * Check if the set of bytes that should be used is all undefined, or all undefined data types. - * It means that whatever laid things down here only knew that something was accessed of some size. - * - * @param lenBytes - * - * @return false if data couldn't be cleared away - */ + * Check if the set of bytes that should be used is all undefined, or all undefined data types. + * It means that whatever laid things down here only knew that something was accessed of + * some size. + * + * @param program + * @param start + * @param lenBytes + * @return false if data couldn't be cleared away + */ private boolean clearAllUndefined(Program program, Address start, int lenBytes) { if (lenBytes < 1) { return false; @@ -1021,7 +1024,7 @@ public class OperandReferenceAnalyzer extends AbstractAnalyzer { if (doit && clearAllUndefined(program, target, program.getDefaultPointerSize())) { DataType adt = program.getDataTypeManager().addDataType(new PointerDataType(), null); - Command cmd = new CreateDataCmd(target, adt); + CreateDataCmd cmd = new CreateDataCmd(target, adt); cmd.applyTo(program); } return true; @@ -1034,8 +1037,10 @@ public class OperandReferenceAnalyzer extends AbstractAnalyzer { /** * Check if the address is in the Relocation table. * This only counts for relocatable programs. Every address should be in the relocation table. + * + * @param program program to check * @param target location to check - * @return + * @return true if target is valid relocation address */ private boolean isValidRelocationAddress(Program program, Address target) { // If the program is relocatable, and this address is not one of the relocations @@ -1210,10 +1215,11 @@ public class OperandReferenceAnalyzer extends AbstractAnalyzer { /** * getWStrLen - * @param ad = address where unicode string is supposed to begin + * + * @param memory program memory to check + * @param ad address where unicode string is supposed to begin * @return number of unicode chars in string, -1 if not * a unicode string. NOTE: Only English strings are considered. - * */ int getWStrLen(Memory memory, Address ad) { try { @@ -1240,8 +1246,8 @@ public class OperandReferenceAnalyzer extends AbstractAnalyzer { @Override public void registerOptions(Options options, Program program) { - HelpLocation helpLocation = new HelpLocation("AutoAnalysisPlugin", - "Auto_Analysis_Option_Instructions"); + HelpLocation helpLocation = + new HelpLocation("AutoAnalysisPlugin", "Auto_Analysis_Option_Instructions"); if (minimumAddressTableSize == -1) { calculateMinimumAddressTableSize(program); diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/bookmark/BookmarkDeleteBackgroundCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/bookmark/BookmarkDeleteBackgroundCmd.java index c22b937ef1..39f7fc6fa3 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/bookmark/BookmarkDeleteBackgroundCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/bookmark/BookmarkDeleteBackgroundCmd.java @@ -1,6 +1,5 @@ /* ### * IP: GHIDRA - * REVIEWED: YES * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,14 +16,13 @@ package ghidra.app.plugin.core.bookmark; import ghidra.framework.cmd.BackgroundCommand; -import ghidra.framework.model.DomainObject; import ghidra.program.model.listing.*; import ghidra.util.task.TaskMonitor; /** * Command to delete a number of bookmarks. */ -public class BookmarkDeleteBackgroundCmd extends BackgroundCommand { +public class BookmarkDeleteBackgroundCmd extends BackgroundCommand { private Bookmark[] bookmarks; @@ -41,8 +39,8 @@ public class BookmarkDeleteBackgroundCmd extends BackgroundCommand { * @see ghidra.framework.cmd.BackgroundCommand#applyTo(ghidra.framework.model.DomainObject, ghidra.util.task.TaskMonitor) */ @Override - public boolean applyTo(DomainObject obj, TaskMonitor monitor) { - BookmarkManager mgr = ((Program) obj).getBookmarkManager(); + public boolean applyTo(Program program, TaskMonitor monitor) { + BookmarkManager mgr = program.getBookmarkManager(); monitor.initialize(bookmarks.length); for (int i = 0; i < bookmarks.length; i++) { if (monitor.isCancelled()) { diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/bookmark/BookmarkDeleteCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/bookmark/BookmarkDeleteCmd.java index 6d8d50ec86..ccb88bee71 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/bookmark/BookmarkDeleteCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/bookmark/BookmarkDeleteCmd.java @@ -19,7 +19,6 @@ import java.util.Collections; import java.util.List; import ghidra.framework.cmd.Command; -import ghidra.framework.model.DomainObject; import ghidra.program.model.address.*; import ghidra.program.model.listing.*; import ghidra.util.exception.CancelledException; @@ -33,7 +32,7 @@ import ghidra.util.task.TaskMonitor; * by type of bookmark * by category of bookmark */ -public class BookmarkDeleteCmd implements Command { +public class BookmarkDeleteCmd implements Command { private List bookmarks; private String type; @@ -162,9 +161,9 @@ public class BookmarkDeleteCmd implements Command { } @Override - public boolean applyTo(DomainObject obj) { + public boolean applyTo(Program program) { - BookmarkManager mgr = ((Program) obj).getBookmarkManager(); + BookmarkManager mgr = program.getBookmarkManager(); if (bookmarks != null) { deleteBookmarks(mgr, bookmarks); diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/bookmark/BookmarkEditCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/bookmark/BookmarkEditCmd.java index 7228df8b16..504de20dfe 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/bookmark/BookmarkEditCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/bookmark/BookmarkEditCmd.java @@ -16,7 +16,6 @@ package ghidra.app.plugin.core.bookmark; import ghidra.framework.cmd.Command; -import ghidra.framework.model.DomainObject; import ghidra.program.model.address.*; import ghidra.program.model.listing.*; @@ -28,7 +27,7 @@ import ghidra.program.model.listing.*; * 2) at a given address * 3) by the information contained in a Bookmark */ -public class BookmarkEditCmd implements Command { +public class BookmarkEditCmd implements Command { private String category; private String comment; @@ -94,9 +93,9 @@ public class BookmarkEditCmd implements Command { } @Override - public boolean applyTo(DomainObject obj) { + public boolean applyTo(Program program) { - BookmarkManager mgr = ((Program) obj).getBookmarkManager(); + BookmarkManager mgr = program.getBookmarkManager(); if (bookmark != null) { bookmark.set(category, comment); diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/bookmark/BookmarkProvider.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/bookmark/BookmarkProvider.java index ab09f93377..ec98e56e64 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/bookmark/BookmarkProvider.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/bookmark/BookmarkProvider.java @@ -396,7 +396,7 @@ public class BookmarkProvider extends ComponentProviderAdapter { } - private static class BookmarkRowObjectDeleteCommand extends BackgroundCommand { + private static class BookmarkRowObjectDeleteCommand extends BackgroundCommand { private List bookmarkList; public BookmarkRowObjectDeleteCommand(List bookmarkList) { @@ -419,14 +419,14 @@ public class BookmarkProvider extends ComponentProviderAdapter { } @Override - public boolean applyTo(DomainObject obj, TaskMonitor monitor) { - boolean wasEabled = obj.isSendingEvents(); + public boolean applyTo(Program program, TaskMonitor monitor) { + boolean wasEabled = program.isSendingEvents(); try { - obj.setEventsEnabled(false); - return doApplyTo(obj, monitor); + program.setEventsEnabled(false); + return doApplyTo(program, monitor); } finally { - obj.setEventsEnabled(wasEabled); + program.setEventsEnabled(wasEabled); } } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/clear/ClearCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/clear/ClearCmd.java index 5342a94aa8..f3b1b08bec 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/clear/ClearCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/clear/ClearCmd.java @@ -19,7 +19,6 @@ import java.util.Iterator; import java.util.Set; import ghidra.framework.cmd.BackgroundCommand; -import ghidra.framework.model.DomainObject; import ghidra.program.model.address.*; import ghidra.program.model.lang.Register; import ghidra.program.model.listing.*; @@ -28,9 +27,8 @@ import ghidra.util.Msg; import ghidra.util.Swing; import ghidra.util.exception.CancelledException; import ghidra.util.task.TaskMonitor; -import ghidra.util.task.TaskMonitorAdapter; -public class ClearCmd extends BackgroundCommand { +public class ClearCmd extends BackgroundCommand { private static final int EVENT_LIMIT = 1000; private AddressSetView view; @@ -76,22 +74,22 @@ public class ClearCmd extends BackgroundCommand { } @Override - public boolean applyTo(DomainObject obj, TaskMonitor monitor) { + public boolean applyTo(Program program, TaskMonitor monitor) { - boolean wasEabled = obj.isSendingEvents(); + boolean wasEabled = program.isSendingEvents(); try { - obj.setEventsEnabled(sendIndividualEvents); - return doApplyTo(obj, monitor); + program.setEventsEnabled(sendIndividualEvents); + return doApplyTo(program, monitor); } finally { - obj.setEventsEnabled(wasEabled); + program.setEventsEnabled(wasEabled); } } - private boolean doApplyTo(DomainObject obj, TaskMonitor monitor) { + private boolean doApplyTo(Program program, TaskMonitor monitor) { try { - doApplyWithCancel(obj, monitor); + doApplyWithCancel(program, monitor); monitor.setMessage("Clear completed"); return true; } @@ -100,14 +98,13 @@ public class ClearCmd extends BackgroundCommand { } } - private boolean doApplyWithCancel(DomainObject obj, TaskMonitor monitor) + private boolean doApplyWithCancel(Program program, TaskMonitor monitor) throws CancelledException { if (monitor == null) { monitor = TaskMonitor.DUMMY; } - Program program = (Program) obj; if (options == null) { clearCode(program, view, monitor); return true; diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/clear/ClearFlowAndRepairCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/clear/ClearFlowAndRepairCmd.java index f20881e899..c44d032b3c 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/clear/ClearFlowAndRepairCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/clear/ClearFlowAndRepairCmd.java @@ -21,7 +21,6 @@ import ghidra.app.cmd.disassemble.DisassembleCommand; import ghidra.app.cmd.function.CreateFunctionCmd; import ghidra.app.plugin.core.analysis.AutoAnalysisManager; import ghidra.framework.cmd.BackgroundCommand; -import ghidra.framework.model.DomainObject; import ghidra.program.database.function.OverlappingFunctionException; import ghidra.program.disassemble.Disassembler; import ghidra.program.disassemble.DisassemblerContextImpl; @@ -35,7 +34,7 @@ import ghidra.util.Msg; import ghidra.util.exception.CancelledException; import ghidra.util.task.TaskMonitor; -public class ClearFlowAndRepairCmd extends BackgroundCommand { +public class ClearFlowAndRepairCmd extends BackgroundCommand { private static final int FALLTHROUGH_SEARCH_LIMIT = 12; @@ -72,12 +71,11 @@ public class ClearFlowAndRepairCmd extends BackgroundCommand { } @Override - public boolean applyTo(DomainObject obj, TaskMonitor monitor) { + public boolean applyTo(Program program, TaskMonitor monitor) { try { monitor.setMessage("Examining code flow..."); - Program program = (Program) obj; Listing listing = program.getListing(); Stack

todoStarts = new Stack<>(); @@ -207,15 +205,13 @@ public class ClearFlowAndRepairCmd extends BackgroundCommand { opts.setClearSymbols(clearLabels); ClearCmd clear = new ClearCmd(clearSet, opts); - clear.applyTo(obj, monitor); + clear.applyTo(program, monitor); if (clearData && clearLabels) { // Clear dereferenced symbols SymbolTable symTable = program.getSymbolTable(); - Iterator
iter = ptrDestinations.iterator(); - while (iter.hasNext()) { + for (Address addr : ptrDestinations) { monitor.checkCancelled(); - Address addr = iter.next(); Symbol[] syms = symTable.getSymbols(addr); for (Symbol sym : syms) { if (sym.getSource() == SourceType.DEFAULT) { @@ -341,9 +337,6 @@ public class ClearFlowAndRepairCmd extends BackgroundCommand { * @param program * @param fromInstrAddr existing instruction address to be used for * context regeneration - * @param flowFallthrough true if fall-through location is clear and - * is the intended disassembly start location, else only the future - * flow context state is needed. * @param context disassembly context. */ private void repairFlowContextFrom(Program program, Address fromInstrAddr, @@ -604,10 +597,8 @@ public class ClearFlowAndRepairCmd extends BackgroundCommand { } } - Iterator
entryIter = starts.iterator(); - while (entryIter.hasNext()) { + for (Address entry : starts) { monitor.checkCancelled(); - Address entry = entryIter.next(); CreateFunctionCmd cmd = new CreateFunctionCmd(entry); cmd.applyTo(program, monitor); } @@ -742,10 +733,8 @@ public class ClearFlowAndRepairCmd extends BackgroundCommand { ReferenceManager refMgr = program.getReferenceManager(); FunctionManager functionManager = program.getFunctionManager(); - Iterator vertexIter = vertexMap.values().iterator(); - while (vertexIter.hasNext()) { + for (BlockVertex v : vertexMap.values()) { monitor.checkCancelled(); - BlockVertex v = vertexIter.next(); if (v == startVertex || v.srcVertices.isEmpty()) { continue; } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/colorizer/ClearColorCommand.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/colorizer/ClearColorCommand.java index 493392c7e1..8ebc290c96 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/colorizer/ClearColorCommand.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/colorizer/ClearColorCommand.java @@ -1,6 +1,5 @@ /* ### * IP: GHIDRA - * REVIEWED: YES * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,7 +19,7 @@ import ghidra.framework.cmd.Command; import ghidra.framework.model.DomainObject; import ghidra.program.model.address.AddressSetView; -class ClearColorCommand implements Command { +class ClearColorCommand implements Command { private final AddressSetView set; private final ColorizingService colorizingService; diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/colorizer/SetColorCommand.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/colorizer/SetColorCommand.java index a52f09cf18..9359ef67fa 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/colorizer/SetColorCommand.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/colorizer/SetColorCommand.java @@ -1,6 +1,5 @@ /* ### * IP: GHIDRA - * REVIEWED: YES * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,14 +15,14 @@ */ package ghidra.app.plugin.core.colorizer; +import java.awt.Color; + import ghidra.framework.cmd.Command; import ghidra.framework.model.DomainObject; import ghidra.program.model.address.*; import ghidra.program.model.listing.Program; -import java.awt.Color; - -class SetColorCommand implements Command { +class SetColorCommand implements Command { private final Color color; private final AddressSetView set; diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/datamgr/archive/DataTypeManagerHandler.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/datamgr/archive/DataTypeManagerHandler.java index c2d36b183c..85e41b4365 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/datamgr/archive/DataTypeManagerHandler.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/datamgr/archive/DataTypeManagerHandler.java @@ -438,8 +438,7 @@ public class DataTypeManagerHandler { } public FileArchive openArchive(ResourceFile file, boolean acquireWriteLock, - boolean isUserAction) - throws IOException, DuplicateIdException { + boolean isUserAction) throws IOException, DuplicateIdException { file = file.getCanonicalFile(); @@ -1282,45 +1281,43 @@ public class DataTypeManagerHandler { } - public void save(UndoableDomainObject undoableDomainObject) { + public void save(DomainObject domainObject) { - tool.prepareToSave(undoableDomainObject); - if (acquireSaveLock(undoableDomainObject)) { + tool.prepareToSave(domainObject); + if (acquireSaveLock(domainObject)) { try { - DomainFileSaveTask task = new DomainFileSaveTask(CONTENT_NAME, - undoableDomainObject.getDomainFile(), tool); + DomainFileSaveTask task = + new DomainFileSaveTask(CONTENT_NAME, domainObject.getDomainFile(), tool); new TaskLauncher(task, tool.getToolFrame()); } finally { - undoableDomainObject.unlock(); + domainObject.unlock(); } } } - public void saveAs(UndoableDomainObject undoableDomainObject) { - if (!getSaveAsLock(undoableDomainObject)) { + public void saveAs(DomainObject domainObject) { + if (!getSaveAsLock(domainObject)) { return; } try { DataTreeDialog dialog = getSaveDialog(); -// dialog.setNameText(undoableDomainObject.getDomainFile().getName()); treeDialogCancelled = true; tool.showDialog(dialog); if (!treeDialogCancelled) { - saveAs(undoableDomainObject, dialog.getDomainFolder(), dialog.getNameText()); + saveAs(domainObject, dialog.getDomainFolder(), dialog.getNameText()); } } finally { - undoableDomainObject.unlock(); + domainObject.unlock(); } } - private void saveAs(UndoableDomainObject undoableDomainObject, DomainFolder folder, - String name) { + private void saveAs(DomainObject domainObject, DomainFolder folder, String name) { DomainFile existingFile = folder.getFile(name); - if (existingFile == undoableDomainObject.getDomainFile()) { - save(undoableDomainObject); + if (existingFile == domainObject.getDomainFile()) { + save(domainObject); return; } if (existingFile != null) { @@ -1330,24 +1327,23 @@ public class DataTypeManagerHandler { return; } } - tool.prepareToSave(undoableDomainObject); - DomainObjectSaveAsTask task = new DomainObjectSaveAsTask(CONTENT_NAME, undoableDomainObject, - folder, name, existingFile != null); + tool.prepareToSave(domainObject); + DomainObjectSaveAsTask task = new DomainObjectSaveAsTask(CONTENT_NAME, domainObject, folder, + name, existingFile != null); new TaskLauncher(task, tool.getToolFrame()); } - private boolean acquireSaveLock(UndoableDomainObject undoableDomainObject) { - if (!undoableDomainObject.lock(null)) { + private boolean acquireSaveLock(DomainObject domainObject) { + if (!domainObject.lock(null)) { String title = "Save " + CONTENT_NAME + " (Busy)"; StringBuilder buf = new StringBuilder(); buf.append("The " + CONTENT_NAME + " is currently being modified by \n"); buf.append("the following actions:\n "); - TransactionInfo t = undoableDomainObject.getCurrentTransactionInfo(); + TransactionInfo t = domainObject.getCurrentTransactionInfo(); List list = t.getOpenSubTransactions(); - Iterator it = list.iterator(); - while (it.hasNext()) { + for (String element : list) { buf.append("\n "); - buf.append(it.next()); + buf.append(element); } buf.append("\n \n"); buf.append( @@ -1362,7 +1358,7 @@ public class DataTypeManagerHandler { "Save Archive!", OptionDialog.WARNING_MESSAGE); if (result == OptionDialog.OPTION_ONE) { - undoableDomainObject.forceLock(true, "Save Archive"); + domainObject.forceLock(true, "Save Archive"); return true; } return false; @@ -1370,18 +1366,17 @@ public class DataTypeManagerHandler { return true; } - private boolean getSaveAsLock(UndoableDomainObject undoableDomainObject) { - if (!undoableDomainObject.lock(null)) { + private boolean getSaveAsLock(DomainObject domainObject) { + if (!domainObject.lock(null)) { String title = "Save " + CONTENT_NAME + " As (Busy)"; StringBuffer buf = new StringBuffer(); buf.append("The " + CONTENT_NAME + " is currently being modified by the following actions/tasks:\n \n"); - TransactionInfo t = undoableDomainObject.getCurrentTransactionInfo(); + TransactionInfo t = domainObject.getCurrentTransactionInfo(); List list = t.getOpenSubTransactions(); - Iterator it = list.iterator(); - while (it.hasNext()) { + for (String element : list) { buf.append("\n "); - buf.append(it.next()); + buf.append(element); } buf.append("\n \n"); buf.append( @@ -1401,11 +1396,11 @@ public class DataTypeManagerHandler { OptionDialog.WARNING_MESSAGE); if (result == OptionDialog.OPTION_ONE) { - undoableDomainObject.forceLock(true, "Save Archive As"); + domainObject.forceLock(true, "Save Archive As"); return true; } else if (result == OptionDialog.OPTION_TWO) { - undoableDomainObject.forceLock(false, "Save Archive As"); + domainObject.forceLock(false, "Save Archive As"); return true; } return false; @@ -1446,9 +1441,8 @@ public class DataTypeManagerHandler { private CreateDataTypeArchiveDataTreeDialog getCreateDialog() { - CreateDataTypeArchiveDataTreeDialog dialog = - new CreateDataTypeArchiveDataTreeDialog(null, "Create", - DataTreeDialog.CREATE, createArchiveFileFilter); + CreateDataTypeArchiveDataTreeDialog dialog = new CreateDataTypeArchiveDataTreeDialog(null, + "Create", DataTreeDialog.CREATE, createArchiveFileFilter); ActionListener listener = event -> { DomainFolder folder = dialog.getDomainFolder(); @@ -1529,8 +1523,7 @@ public class DataTypeManagerHandler { } catch (IOException e) { setStatusText("Unexpected IOException!"); - Msg.showError(null, getComponent(), "Unexpected Exception", - e.getMessage(), e); + Msg.showError(null, getComponent(), "Unexpected Exception", e.getMessage(), e); } return false; @@ -1581,12 +1574,12 @@ public class DataTypeManagerHandler { static class DomainObjectSaveAsTask extends Task { private String domainObjectType; - private UndoableDomainObject domainObject; + private DomainObject domainObject; private DomainFolder parentFolder; private String newName; private boolean doOverwrite; - DomainObjectSaveAsTask(String domainObjectType, UndoableDomainObject domainObject, + DomainObjectSaveAsTask(String domainObjectType, DomainObject domainObject, DomainFolder folder, String newName, boolean doOverwrite) { super("Save " + domainObjectType + " As", true, true, true); @@ -1628,9 +1621,7 @@ public class DataTypeManagerHandler { .equals(file.getContentType())) { return; } - Iterator archiveIter = openArchives.iterator(); - while (archiveIter.hasNext()) { - Archive archive = archiveIter.next(); + for (Archive archive : openArchives) { if (archive instanceof ProjectArchive) { ProjectArchive projectArchive = (ProjectArchive) archive; DomainFile domainFile = projectArchive.getDomainFile(); @@ -1651,9 +1642,7 @@ public class DataTypeManagerHandler { @Override public void domainFileObjectReplaced(DomainFile file, DomainObject oldObject) { if (oldObject instanceof DataTypeArchiveDB) { - Iterator archiveIter = openArchives.iterator(); - while (archiveIter.hasNext()) { - Archive archive = archiveIter.next(); + for (Archive archive : openArchives) { if (archive instanceof ProjectArchive) { ProjectArchive projectArchive = (ProjectArchive) archive; DomainObject domainObject = projectArchive.getDomainObject(); @@ -1674,9 +1663,7 @@ public class DataTypeManagerHandler { } String newName = file.getName(); String fileID = file.getFileID(); - Iterator archiveIter = openArchives.iterator(); - while (archiveIter.hasNext()) { - Archive archive = archiveIter.next(); + for (Archive archive : openArchives) { if (!archive.isModifiable()) { continue; } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/equate/ConvertCommand.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/equate/ConvertCommand.java index 617fab6588..53687a9791 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/equate/ConvertCommand.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/equate/ConvertCommand.java @@ -24,7 +24,6 @@ import ghidra.app.context.ListingActionContext; import ghidra.docking.settings.FormatSettingsDefinition; import ghidra.docking.settings.Settings; import ghidra.framework.cmd.BackgroundCommand; -import ghidra.framework.model.DomainObject; import ghidra.program.model.address.Address; import ghidra.program.model.data.AbstractIntegerDataType; import ghidra.program.model.data.DataType; @@ -36,7 +35,7 @@ import ghidra.program.model.util.CodeUnitInsertionException; import ghidra.program.util.ProgramSelection; import ghidra.util.task.TaskMonitor; -public class ConvertCommand extends BackgroundCommand { +public class ConvertCommand extends BackgroundCommand { private Program program; private AbstractConvertAction action; private ListingActionContext context; @@ -66,7 +65,7 @@ public class ConvertCommand extends BackgroundCommand { } @Override - public boolean applyTo(DomainObject obj, TaskMonitor monitor) { + public boolean applyTo(Program program, TaskMonitor monitor) { try { CodeUnit cu = action.plugin.getCodeUnit(context); diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/equate/CreateEnumEquateCommand.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/equate/CreateEnumEquateCommand.java index 9d4563f15f..f1fb55ef47 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/equate/CreateEnumEquateCommand.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/equate/CreateEnumEquateCommand.java @@ -18,7 +18,6 @@ package ghidra.app.plugin.core.equate; import java.util.*; import ghidra.framework.cmd.BackgroundCommand; -import ghidra.framework.model.DomainObject; import ghidra.program.database.symbol.EquateManager; import ghidra.program.model.address.Address; import ghidra.program.model.address.AddressSetView; @@ -31,7 +30,7 @@ import ghidra.util.Msg; import ghidra.util.exception.*; import ghidra.util.task.TaskMonitor; -public class CreateEnumEquateCommand extends BackgroundCommand { +public class CreateEnumEquateCommand extends BackgroundCommand { private AddressSetView addresses; private Enum enoom; @@ -47,9 +46,7 @@ public class CreateEnumEquateCommand extends BackgroundCommand { * @param enoom The enum to apply equates with * @param shouldDoOnSubOps true if the enum should also be applied to the sub-operands. */ - public CreateEnumEquateCommand(Program program, AddressSetView addresses, Enum enoom, - boolean shouldDoOnSubOps) { - this.program = Objects.requireNonNull(program); + public CreateEnumEquateCommand(AddressSetView addresses, Enum enoom, boolean shouldDoOnSubOps) { this.addresses = Objects.requireNonNull(addresses); this.enoom = Objects.requireNonNull(enoom); this.shouldDoOnSubOps = shouldDoOnSubOps; @@ -61,7 +58,8 @@ public class CreateEnumEquateCommand extends BackgroundCommand { } @Override - public boolean applyTo(DomainObject obj, TaskMonitor monitor) { + public boolean applyTo(Program p, TaskMonitor monitor) { + this.program = p; monitor.setIndeterminate(true); monitor.setMessage("Installing Equate"); diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/equate/CreateEquateCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/equate/CreateEquateCmd.java index 7fee66677f..c70cc6386b 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/equate/CreateEquateCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/equate/CreateEquateCmd.java @@ -20,8 +20,6 @@ import java.util.Objects; import ghidra.app.cmd.equate.SetEquateCmd; import ghidra.app.context.ListingActionContext; import ghidra.framework.cmd.BackgroundCommand; -import ghidra.framework.cmd.Command; -import ghidra.framework.model.DomainObject; import ghidra.program.database.symbol.EquateManager; import ghidra.program.model.address.Address; import ghidra.program.model.data.Enum; @@ -36,7 +34,7 @@ import ghidra.util.task.TaskMonitor; /** * Class to handle creating new equates for a selection or the whole program */ -public class CreateEquateCmd extends BackgroundCommand { +public class CreateEquateCmd extends BackgroundCommand { private CodeUnitIterator iterator; //iterator over selected instructions or null if no selection private String equateName; // user defined equate name @@ -84,7 +82,7 @@ public class CreateEquateCmd extends BackgroundCommand { } @Override - public boolean applyTo(DomainObject domain, TaskMonitor monitor) { + public boolean applyTo(Program program, TaskMonitor monitor) { monitor.setIndeterminate(true); monitor.setMessage("Creating Equate"); @@ -92,16 +90,16 @@ public class CreateEquateCmd extends BackgroundCommand { while (iterator.hasNext() && !monitor.isCancelled()) { CodeUnit cu = iterator.next(); if (cu instanceof Instruction) { - maybeCreateEquate(domain, (Instruction) cu); + maybeCreateEquate(program, (Instruction) cu); } else if (cu instanceof Data) { - maybeCreateEquate(domain, (Data) cu); + maybeCreateEquate(program, (Data) cu); } } return true; } - private void maybeCreateEquate(DomainObject domain, Data data) { + private void maybeCreateEquate(Program program, Data data) { if (!data.isDefined()) { return; @@ -118,10 +116,10 @@ public class CreateEquateCmd extends BackgroundCommand { } int opIndex = getOperandIndex(); - createEquate(domain, data, opIndex, scalar); + createEquate(program, data, opIndex, scalar); } - private void maybeCreateEquate(DomainObject domain, Instruction instruction) { + private void maybeCreateEquate(Program program, Instruction instruction) { for (int opIndex = 0; opIndex < instruction.getNumOperands(); opIndex++) { Object[] opObjects = instruction.getOpObjects(opIndex); for (Object opObject : opObjects) { @@ -134,13 +132,12 @@ public class CreateEquateCmd extends BackgroundCommand { continue; } - createEquate(domain, instruction, opIndex, scalar); + createEquate(program, instruction, opIndex, scalar); } } } - private void createEquate(DomainObject domain, CodeUnit codeUnit, int opIndex, - Scalar scalar) { + private void createEquate(Program program, CodeUnit codeUnit, int opIndex, Scalar scalar) { EquateTable equateTable = codeUnit.getProgram().getEquateTable(); Address address = codeUnit.getAddress(); @@ -151,12 +148,13 @@ public class CreateEquateCmd extends BackgroundCommand { } if (curEquate == null) { - Command cmd = new SetEquateCmd(equateName, address, opIndex, targetScalarValue); - cmd.applyTo(domain); + SetEquateCmd cmd = new SetEquateCmd(equateName, address, opIndex, targetScalarValue); + cmd.applyTo(program); } else if (overwriteExisting) { - Command cmd = new RenameEquateCmd(curEquate.getName(), equateName, address, opIndex); - cmd.applyTo(domain); + RenameEquateCmd cmd = + new RenameEquateCmd(curEquate.getName(), equateName, address, opIndex); + cmd.applyTo(program); } } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/equate/EquatePlugin.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/equate/EquatePlugin.java index 22451a8552..19f9ee5d35 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/equate/EquatePlugin.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/equate/EquatePlugin.java @@ -182,9 +182,8 @@ public class EquatePlugin extends Plugin { iter = listing.getCodeUnits(context.getProgram().getMemory(), true); } - BackgroundCommand cmd = - new CreateEquateCmd(scalar, iter, dialog.getEquateName(), - dialog.getOverwriteExisting(), context); + BackgroundCommand cmd = new CreateEquateCmd(scalar, iter, dialog.getEquateName(), + dialog.getOverwriteExisting(), context); tool.executeBackgroundCommand(cmd, context.getProgram()); dialog.dispose(); @@ -214,7 +213,7 @@ public class EquatePlugin extends Plugin { boolean shouldDoOnSubOps = dialog.shouldApplyOnSubOps(); Program program = context.getProgram(); CreateEnumEquateCommand cmd = - new CreateEnumEquateCommand(program, addresses, (Enum) dataType, shouldDoOnSubOps); + new CreateEnumEquateCommand(addresses, (Enum) dataType, shouldDoOnSubOps); tool.executeBackgroundCommand(cmd, program); dialog.dispose(); @@ -287,8 +286,7 @@ public class EquatePlugin extends Plugin { } private void renameEquate(ListingActionContext context, Enum enoom, Equate oldEquate, - String newEquateName, - CodeUnitIterator iter) { + String newEquateName, CodeUnitIterator iter) { // First do a sanity check to make sure we're not trying to change to a duplicate // name. @@ -337,8 +335,7 @@ public class EquatePlugin extends Plugin { } private RenameEquateCmd createRenameCmd(Enum enoom, String oldName, String newName, - Address addr, - int opIndex) { + Address addr, int opIndex) { if (enoom != null) { return new RenameEquateCmd(oldName, enoom, addr, opIndex); @@ -374,8 +371,7 @@ public class EquatePlugin extends Plugin { Program program = context.getProgram(); List opIndexes = getInstructionMatches(program, instr, equate); for (Integer opIndexe : opIndexes) { - bckCmd.add( - new ClearEquateCmd(equate.getName(), instr.getAddress(), opIndexe)); + bckCmd.add(new ClearEquateCmd(equate.getName(), instr.getAddress(), opIndexe)); } } else if (cu instanceof Data) { diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/equate/EquateTablePlugin.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/equate/EquateTablePlugin.java index dc46ef86b0..05e0d81f91 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/equate/EquateTablePlugin.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/equate/EquateTablePlugin.java @@ -158,7 +158,7 @@ public class EquateTablePlugin extends ProgramPlugin implements DomainObjectList OptionDialog.QUESTION_MESSAGE); if (option != OptionDialog.CANCEL_OPTION) { - tool.execute(new RemoveEquateCmd(equateNames, getTool()), currentProgram); + tool.execute(new RemoveEquateCmd(equateNames), currentProgram); } } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/equate/RemoveEquateCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/equate/RemoveEquateCmd.java index c4a56bafa4..43865c5956 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/equate/RemoveEquateCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/equate/RemoveEquateCmd.java @@ -16,37 +16,25 @@ package ghidra.app.plugin.core.equate; import ghidra.framework.cmd.Command; -import ghidra.framework.model.DomainObject; -import ghidra.framework.plugintool.PluginTool; import ghidra.program.model.listing.Program; import ghidra.program.model.symbol.EquateTable; +import ghidra.util.Msg; /** * Command for removing all references to an equate. */ -class RemoveEquateCmd implements Command { +class RemoveEquateCmd implements Command { private String[] equateNames; private String msg; - private PluginTool tool; /** * Constructor - * @param equateName name of equate to be removed. + * @param equateNames one or more equate names to be removed. */ - RemoveEquateCmd(String equateName, PluginTool tool) { - this.equateNames = new String[] { equateName }; - this.tool = tool; - } - - /** - * Constructor - * @param equateName name of equate to be removed. - */ - RemoveEquateCmd(String[] equateNames, PluginTool tool) { + RemoveEquateCmd(String... equateNames) { this.equateNames = equateNames; - this.tool = tool; } /** @@ -57,18 +45,14 @@ class RemoveEquateCmd implements Command { return "Remove Equate" + (equateNames.length > 1 ? "s" : ""); } - /** - * @see ghidra.framework.cmd.Command#applyTo(ghidra.framework.plugintool.PluginTool, ghidra.framework.model.DomainObject) - */ @Override - public boolean applyTo(DomainObject obj) { + public boolean applyTo(Program program) { - EquateTable etable = ((Program) obj).getEquateTable(); + EquateTable etable = program.getEquateTable(); boolean success = true; - for (int i = 0; i < equateNames.length; i++) { - String name = equateNames[i]; + for (String name : equateNames) { if (!etable.removeEquate(name)) { - tool.setStatusInfo("Unable to remove equate: " + name); + Msg.error(this, "Failed to remove equate: " + name); success = false; } } @@ -78,9 +62,6 @@ class RemoveEquateCmd implements Command { return success; } - /** - * @see ghidra.framework.cmd.Command#getStatusMsg() - */ @Override public String getStatusMsg() { return msg; diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/equate/RenameEquateCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/equate/RenameEquateCmd.java index d71363c42e..13c6a31903 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/equate/RenameEquateCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/equate/RenameEquateCmd.java @@ -16,7 +16,6 @@ package ghidra.app.plugin.core.equate; import ghidra.framework.cmd.Command; -import ghidra.framework.model.DomainObject; import ghidra.program.database.symbol.EquateManager; import ghidra.program.model.address.Address; import ghidra.program.model.data.Enum; @@ -31,7 +30,7 @@ import ghidra.util.exception.*; * add the current location to its list of references. The old equate will have this * reference location removed and will be deleted if it was the last reference. */ -class RenameEquateCmd implements Command { +class RenameEquateCmd implements Command { private String oldEquateName; private String newEquateName; @@ -79,22 +78,15 @@ class RenameEquateCmd implements Command { this.opIndex = opIndex; } - /** - * The name of the edit action. - */ @Override public String getName() { return "Rename Equate"; } - /** - * @see ghidra.framework.cmd.Command#applyTo(ghidra.framework.plugintool.PluginTool, ghidra.framework.model.DomainObject) - */ @Override - public boolean applyTo(DomainObject obj) { - Program program = ((Program) obj); + public boolean applyTo(Program program) { EquateTable etable = program.getEquateTable(); - + // First make sure there's an entry in the equates table for the equate // to be changed (there should always be one). Equate fromEquate = etable.getEquate(oldEquateName); @@ -102,10 +94,10 @@ class RenameEquateCmd implements Command { msg = "Equate not found: " + oldEquateName; return false; } - + // Get the value behind the equate...for later use. long value = fromEquate.getValue(); - + // See if there are 0 references to this equate. If so, remove // it from the table. if (fromEquate.getReferenceCount() <= 1) { @@ -142,9 +134,6 @@ class RenameEquateCmd implements Command { return true; } - /** - * @see ghidra.framework.cmd.Command#getStatusMsg() - */ @Override public String getStatusMsg() { return msg; diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/equate/RenameEquatesCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/equate/RenameEquatesCmd.java index b1fcc94d41..df42474694 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/equate/RenameEquatesCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/equate/RenameEquatesCmd.java @@ -16,7 +16,6 @@ package ghidra.app.plugin.core.equate; import ghidra.framework.cmd.Command; -import ghidra.framework.model.DomainObject; import ghidra.program.model.listing.Program; import ghidra.program.model.symbol.*; import ghidra.util.exception.*; @@ -30,7 +29,7 @@ import ghidra.util.exception.*; * will restore everything back to where it was when this object was created. The * redo method will repeat the rename operation. */ -class RenameEquatesCmd implements Command { +class RenameEquatesCmd implements Command { private String newEquateName; private String oldEquateName; @@ -39,8 +38,7 @@ class RenameEquatesCmd implements Command { /** * Constructor - * @param program the current program - * @param equate the equate to be renamed. + * @param oldEquateName the name of equate to be renamed. * @param newEquateName the new name for the equate */ RenameEquatesCmd(String oldEquateName, String newEquateName) { @@ -48,20 +46,14 @@ class RenameEquatesCmd implements Command { this.newEquateName = newEquateName; } - /** - * The name of the edit action. - */ @Override public String getName() { return "Rename Equates"; } - /** - * @see ghidra.framework.cmd.Command#applyTo(ghidra.framework.plugintool.PluginTool, ghidra.framework.model.DomainObject) - */ @Override - public boolean applyTo(DomainObject obj) { - EquateTable etable = ((Program) obj).getEquateTable(); + public boolean applyTo(Program program) { + EquateTable etable = program.getEquateTable(); // See if there's an entry in the table for the old equate name. There should be, // otherwise there's a problem. @@ -70,7 +62,7 @@ class RenameEquatesCmd implements Command { msg = "Equate not found: " + oldEquateName; return false; } - + // Now get the entry in the Equate table for the new equate name. If there's // already an entry with this name, just use that...otherwise, create a new one. Equate toEquate = etable.getEquate(newEquateName); @@ -96,9 +88,6 @@ class RenameEquatesCmd implements Command { return true; } - /** - * @see ghidra.framework.cmd.Command#getStatusMsg() - */ @Override public String getStatusMsg() { return msg; diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/function/EditThunkFunctionAction.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/function/EditThunkFunctionAction.java index 4cd8de59fd..6545f6f0df 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/function/EditThunkFunctionAction.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/function/EditThunkFunctionAction.java @@ -18,7 +18,6 @@ package ghidra.app.plugin.core.function; import docking.action.MenuData; import ghidra.app.cmd.function.CreateThunkFunctionCmd; import ghidra.app.context.*; -import ghidra.framework.cmd.BackgroundCommand; import ghidra.program.model.address.Address; import ghidra.program.model.listing.*; import ghidra.program.model.symbol.Symbol; @@ -83,7 +82,7 @@ class EditThunkFunctionAction extends ProgramContextAction { Symbol referencedSymbol = dialog.getSymbol(); Address referencedFunctionAddr = dialog.getAddress(); - BackgroundCommand cmd; + CreateThunkFunctionCmd cmd; if (referencedSymbol != null) { cmd = new CreateThunkFunctionCmd(func.getEntryPoint(), null, referencedSymbol); } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/function/FunctionPlugin.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/function/FunctionPlugin.java index ef0f8835d6..ac5485a4e0 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/function/FunctionPlugin.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/function/FunctionPlugin.java @@ -328,13 +328,13 @@ public class FunctionPlugin extends Plugin implements DataService { return maxSize; } - protected void execute(Program program, Command cmd) { + protected void execute(Program program, Command cmd) { if (!tool.execute(cmd, program)) { Msg.showError(this, tool.getToolFrame(), cmd.getName(), cmd.getStatusMsg()); } } - protected void execute(Program program, BackgroundCommand cmd) { + protected void execute(Program program, BackgroundCommand cmd) { tool.executeBackgroundCommand(cmd, program); } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/function/RemoveStackDepthChangeAction.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/function/RemoveStackDepthChangeAction.java index 8fa5c54353..7a99e6f99d 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/function/RemoveStackDepthChangeAction.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/function/RemoveStackDepthChangeAction.java @@ -38,7 +38,6 @@ class RemoveStackDepthChangeAction extends ListingContextAction { /** * Creates a new action with the given name and associated to the given * plugin. - * @param name the name for this action. * @param plugin the plugin this action is associated with. */ RemoveStackDepthChangeAction(FunctionPlugin plugin) { @@ -60,7 +59,7 @@ class RemoveStackDepthChangeAction extends ListingContextAction { if (CallDepthChangeInfo.getStackDepthChange(program, address) == null) { return; // nothing to remove. } - funcPlugin.execute(program, new RemoveStackDepthChangeCommand(program, address)); + funcPlugin.execute(program, new RemoveStackDepthChangeCommand(address)); } @Override diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/function/RevertThunkFunctionAction.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/function/RevertThunkFunctionAction.java index f868fed014..dad77e6d61 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/function/RevertThunkFunctionAction.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/function/RevertThunkFunctionAction.java @@ -88,13 +88,7 @@ class RevertThunkFunctionAction extends ProgramContextAction { return; } - int txId = program.startTransaction("Revert Thunk"); - try { - func.setThunkedFunction(null); - } - finally { - program.endTransaction(txId, true); - } + funcPlugin.getTool().execute("Revert Thunk", program, () -> func.setThunkedFunction(null)); } @Override diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/function/SetStackDepthChangeAction.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/function/SetStackDepthChangeAction.java index fb1783348e..b611894524 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/function/SetStackDepthChangeAction.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/function/SetStackDepthChangeAction.java @@ -21,7 +21,6 @@ import docking.widgets.dialogs.NumberInputDialog; import ghidra.app.cmd.function.*; import ghidra.app.context.ListingActionContext; import ghidra.app.context.ListingContextAction; -import ghidra.framework.cmd.Command; import ghidra.framework.cmd.CompoundCmd; import ghidra.framework.plugintool.PluginTool; import ghidra.program.model.address.Address; @@ -140,13 +139,15 @@ class SetStackDepthChangeAction extends ListingContextAction { return; } // Set the function purge. - Command purgeCmd = new SetFunctionPurgeCommand(function, newFunctionPurgeSize); + SetFunctionPurgeCommand purgeCmd = + new SetFunctionPurgeCommand(function, newFunctionPurgeSize); Integer dephtChange = CallDepthChangeInfo.getStackDepthChange(program, fromAddress); if (dephtChange != null) { // If we have a stack depth change here, remove it since we are setting the purge. - CompoundCmd compoundCmd = new CompoundCmd("Set Function Purge via StackDepthChange"); - compoundCmd.add(new RemoveStackDepthChangeCommand(program, fromAddress)); + CompoundCmd compoundCmd = + new CompoundCmd<>("Set Function Purge via StackDepthChange"); + compoundCmd.add(new RemoveStackDepthChangeCommand(fromAddress)); compoundCmd.add(purgeCmd); funcPlugin.execute(program, compoundCmd); } @@ -177,8 +178,7 @@ class SetStackDepthChangeAction extends ListingContextAction { } private void setStackDepthChange(Program program, Address address, int newStackDepthChange) { - funcPlugin.execute(program, - new SetStackDepthChangeCommand(program, address, newStackDepthChange)); + funcPlugin.execute(program, new SetStackDepthChangeCommand(address, newStackDepthChange)); } @Override diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/memory/ExpandBlockModel.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/memory/ExpandBlockModel.java index 10923ac6ff..9ee7d30352 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/memory/ExpandBlockModel.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/memory/ExpandBlockModel.java @@ -49,7 +49,7 @@ abstract class ExpandBlockModel implements DomainObjectListener { @Override public void domainObjectChanged(DomainObjectChangedEvent ev) { - if (!ev.contains(DomainObjectEvent.RESTORED)) { + if (program == null || !ev.contains(DomainObjectEvent.RESTORED)) { return; } @@ -148,7 +148,7 @@ abstract class ExpandBlockModel implements DomainObjectListener { program = null; } - private class ExpandBlockCmd implements Command { + private class ExpandBlockCmd implements Command { private String msg; private MemoryBlock expandBlock; @@ -157,8 +157,7 @@ abstract class ExpandBlockModel implements DomainObjectListener { } @Override - public boolean applyTo(DomainObject obj) { - Program prog = (Program) obj; + public boolean applyTo(Program prog) { Memory memory = prog.getMemory(); try { String blockName = expandBlock.getName(); diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/memory/ImageBaseDialog.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/memory/ImageBaseDialog.java index 6eda68be9a..7503618a07 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/memory/ImageBaseDialog.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/memory/ImageBaseDialog.java @@ -24,7 +24,6 @@ import javax.swing.event.DocumentListener; import docking.DialogComponentProvider; import ghidra.app.util.HelpTopics; import ghidra.framework.cmd.Command; -import ghidra.framework.model.DomainObject; import ghidra.framework.plugintool.PluginTool; import ghidra.framework.store.LockException; import ghidra.program.database.ProgramDB; @@ -115,7 +114,7 @@ class ImageBaseDialog extends DialogComponentProvider { protected void okCallback() { if (addr != null && !addr.equals(currentAddr)) { Msg.info(this, "old base = " + program.getImageBase()); - Command cmd = new SetBaseCommand(addr); + SetBaseCommand cmd = new SetBaseCommand(addr); if (!tool.execute(cmd, program)) { setStatusText(cmd.getStatusMsg()); return; @@ -127,7 +126,7 @@ class ImageBaseDialog extends DialogComponentProvider { } -class SetBaseCommand implements Command { +class SetBaseCommand implements Command { private Address addr; private String msg; @@ -139,10 +138,9 @@ class SetBaseCommand implements Command { * @see ghidra.framework.cmd.Command#applyTo(ghidra.framework.model.DomainObject) */ @Override - public boolean applyTo(DomainObject obj) { - ProgramDB p = (ProgramDB) obj; + public boolean applyTo(Program program) { try { - p.setImageBase(addr, true); + program.setImageBase(addr, true); } catch (IllegalStateException e) { msg = e.getMessage(); @@ -160,17 +158,11 @@ class SetBaseCommand implements Command { return true; } - /** - * @see ghidra.framework.cmd.Command#getStatusMsg() - */ @Override public String getStatusMsg() { return msg; } - /** - * @see ghidra.framework.cmd.Command#getName() - */ @Override public String getName() { return "Set Image Base"; diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/memory/MemoryMapManager.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/memory/MemoryMapManager.java index 6d7f18c136..61f548bb48 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/memory/MemoryMapManager.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/memory/MemoryMapManager.java @@ -21,7 +21,6 @@ import java.util.List; import docking.widgets.OptionDialog; import ghidra.app.cmd.memory.DeleteBlockCmd; import ghidra.framework.cmd.Command; -import ghidra.framework.model.DomainObject; import ghidra.framework.plugintool.PluginTool; import ghidra.framework.store.LockException; import ghidra.program.model.address.*; @@ -77,7 +76,7 @@ class MemoryMapManager { } } - private void renameFragment(Address start, String name) { + private static void renameFragment(Program program, Address start, String name) { Listing listing = program.getListing(); String[] treeNames = listing.getTreeNames(); @@ -183,6 +182,7 @@ class MemoryMapManager { /** * Delete the list of memory blocks. + * @param blocks list of memory blocks to be removed */ void deleteBlocks(final List blocks) { @@ -236,7 +236,7 @@ class MemoryMapManager { tool.executeBackgroundCommand(cmd, program); } - private class SplitBlockCmd implements Command { + private static class SplitBlockCmd implements Command { private MemoryBlock block; private Address newStart; @@ -250,11 +250,11 @@ class MemoryMapManager { } @Override - public boolean applyTo(DomainObject obj) { - Program p = (Program) obj; - Memory memory = p.getMemory(); + public boolean applyTo(Program program) { - if (!p.hasExclusiveAccess()) { + Memory memory = program.getMemory(); + + if (!program.hasExclusiveAccess()) { msg = "Exclusive access required"; return false; } @@ -300,7 +300,7 @@ class MemoryMapManager { } } - private class MergeBlocksCmd implements Command { + private static class MergeBlocksCmd implements Command { private String msg; private List blocks; @@ -310,9 +310,9 @@ class MemoryMapManager { } @Override - public boolean applyTo(DomainObject obj) { - Program p = (Program) obj; - Memory mem = p.getMemory(); + public boolean applyTo(Program program) { + + Memory mem = program.getMemory(); Address min = null; Address max = null; @@ -376,7 +376,7 @@ class MemoryMapManager { } // Rename the fragment based on the first block - renameFragment(start, bigBlock.getName()); + renameFragment(program, start, bigBlock.getName()); // join block with block after bigBlock = mem.join(bigBlock, nextBlock); diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/memory/MemoryMapModel.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/memory/MemoryMapModel.java index 27ac04fdf0..1b1d53f8a0 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/memory/MemoryMapModel.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/memory/MemoryMapModel.java @@ -361,7 +361,7 @@ class MemoryMapModel extends AbstractSortedTableModel implements Pr if (result == OptionDialog.NO_OPTION) { return; } - UninitializedBlockCmd cmd = new UninitializedBlockCmd(program, block); + UninitializedBlockCmd cmd = new UninitializedBlockCmd(block); provider.getTool().executeBackgroundCommand(cmd, program); } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/memory/MoveBlockModel.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/memory/MoveBlockModel.java index fafef5d295..0bfed6c5c6 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/memory/MoveBlockModel.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/memory/MoveBlockModel.java @@ -56,7 +56,7 @@ class MoveBlockModel implements DomainObjectListener { */ @Override public void domainObjectChanged(DomainObjectChangedEvent ev) { - if (ev.contains(DomainObjectEvent.RESTORED)) { + if (program != null && ev.contains(DomainObjectEvent.RESTORED)) { block = program.getMemory().getBlock(blockStart); } } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/memory/UninitializedBlockCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/memory/UninitializedBlockCmd.java index 7c6e2ddca3..21ac69cf8a 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/memory/UninitializedBlockCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/memory/UninitializedBlockCmd.java @@ -1,6 +1,5 @@ /* ### * IP: GHIDRA - * REVIEWED: YES * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,26 +18,23 @@ package ghidra.app.plugin.core.memory; import ghidra.app.plugin.core.clear.ClearCmd; import ghidra.app.plugin.core.clear.ClearOptions; import ghidra.framework.cmd.BackgroundCommand; -import ghidra.framework.model.DomainObject; import ghidra.program.model.address.AddressSet; import ghidra.program.model.listing.Program; import ghidra.program.model.mem.MemoryBlock; import ghidra.util.exception.RollbackException; import ghidra.util.task.TaskMonitor; -public class UninitializedBlockCmd extends BackgroundCommand { +public class UninitializedBlockCmd extends BackgroundCommand { private MemoryBlock block; - private Program program; - public UninitializedBlockCmd(Program program, MemoryBlock block) { + public UninitializedBlockCmd(MemoryBlock block) { super("Unitialize Memory Block", false, true, true); - this.program = program; this.block = block; } @Override - public boolean applyTo(DomainObject obj, TaskMonitor monitor) throws RuntimeException { + public boolean applyTo(Program program, TaskMonitor monitor) throws RuntimeException { ClearOptions clearOptions = new ClearOptions(false); clearOptions.setClearCode(true); clearOptions.setClearDefaultReferences(true); diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/programtree/ProgramTreeActionManager.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/programtree/ProgramTreeActionManager.java index a437dab6d0..6f8f1f53a7 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/programtree/ProgramTreeActionManager.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/programtree/ProgramTreeActionManager.java @@ -20,6 +20,8 @@ import java.awt.event.InputEvent; import java.awt.event.KeyEvent; import java.io.IOException; import java.util.*; +import java.util.function.Consumer; +import java.util.function.Supplier; import javax.swing.KeyStroke; import javax.swing.event.TreeSelectionEvent; @@ -30,6 +32,8 @@ import javax.swing.tree.TreePath; import docking.ActionContext; import docking.action.*; import docking.dnd.GClipboard; +import docking.widgets.tree.GTreeNode; +import generic.timer.ExpiringSwingTimer; import ghidra.app.cmd.module.*; import ghidra.framework.cmd.CompoundCmd; import ghidra.program.model.address.Address; @@ -1055,6 +1059,22 @@ class ProgramTreeActionManager implements ClipboardOwner { } + private void getModelNode(ProgramNode parent, Group group, Consumer consumer) { + + int expireMs = 3000; + Supplier supplier = () -> { + int nchild = parent.getChildCount(); + for (int i = 0; i < nchild; i++) { + ProgramNode child = (ProgramNode) parent.getChildAt(i); + if (child.getGroup() == group) { + return child; + } + } + return null; + }; + ExpiringSwingTimer.get(supplier, expireMs, consumer); + } + /** * Find the node corresponding to the given group. Start the cell * editor for the child node. @@ -1063,15 +1083,11 @@ class ProgramTreeActionManager implements ClipboardOwner { if (!parent.wasVisited()) { tree.visitNode(parent); } - int nchild = parent.getChildCount(); - for (int i = 0; i < nchild; i++) { - ProgramNode child = (ProgramNode) parent.getChildAt(i); - if (child.getGroup() == group) { - tree.setEditable(true); - tree.startEditingAtPath(child.getTreePath()); - break; - } - } + + getModelNode(parent, group, c -> { + tree.setEditable(true); + tree.startEditingAtPath(c.getTreePath()); + }); } /////////////////////////////////////////////////////////////////////// diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/programtree/ViewPanel.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/programtree/ViewPanel.java index 13e9773a3a..e2f1d8c20d 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/programtree/ViewPanel.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/programtree/ViewPanel.java @@ -18,7 +18,6 @@ package ghidra.app.plugin.core.programtree; import java.awt.*; import java.awt.event.MouseEvent; import java.util.HashMap; -import java.util.Iterator; import javax.swing.*; import javax.swing.event.ChangeEvent; @@ -103,6 +102,9 @@ class ViewPanel extends JPanel implements ChangeListener { boolean removeView(ViewProviderService vps) { String viewName = vps.getViewName(); + if (!map.containsKey(viewName)) { + return false; // view not found (may have already be removed) + } tabbedPane.removeChangeListener(this); // remove us as a listener so that the viewChanged() method is // not called while we are removing the view provider @@ -178,10 +180,8 @@ class ViewPanel extends JPanel implements ChangeListener { tabbedPane.setSelectedComponent(c); // causes a state change event updateLocalActions(v); - Iterator iter = map.keySet().iterator(); - while (iter.hasNext()) { + for (String key : map.keySet()) { - String key = iter.next(); ViewProviderService vps = map.get(key); JComponent comp = vps.getViewComponent(); if (c != comp) { @@ -225,9 +225,7 @@ class ViewPanel extends JPanel implements ChangeListener { } ViewProviderService getViewProviderForComponent(Component component) { - Iterator iter = map.keySet().iterator(); - while (iter.hasNext()) { - String name = iter.next(); + for (String name : map.keySet()) { ViewProviderService v = map.get(name); if (v.getViewComponent() == component) { return v; @@ -357,10 +355,8 @@ class ViewPanel extends JPanel implements ChangeListener { */ private void viewChanged() { JComponent c = (JComponent) tabbedPane.getSelectedComponent(); - Iterator iter = map.keySet().iterator(); - while (iter.hasNext()) { + for (String key : map.keySet()) { - String key = iter.next(); ViewProviderService v = map.get(key); if (c == v.getViewComponent()) { v.setHasFocus(true); diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/references/OffsetTablePlugin.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/references/OffsetTablePlugin.java index 1536b81331..cb71a01366 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/references/OffsetTablePlugin.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/references/OffsetTablePlugin.java @@ -25,7 +25,6 @@ import ghidra.app.plugin.PluginCategoryNames; import ghidra.app.util.HelpTopics; import ghidra.framework.cmd.Command; import ghidra.framework.cmd.CompoundCmd; -import ghidra.framework.model.DomainObject; import ghidra.framework.plugintool.*; import ghidra.framework.plugintool.util.PluginStatus; import ghidra.program.model.address.*; @@ -65,7 +64,7 @@ public class OffsetTablePlugin extends Plugin { private DockingAction refAction; private int lastSelectedSize = 4; private boolean lastSigned = true; - + /** * @param pluginName * @param tool @@ -75,23 +74,22 @@ public class OffsetTablePlugin extends Plugin { createActions(); } - private void createActions() { refAction = new ListingContextAction("Create Offset References", getName()) { @Override - public void actionPerformed(ListingActionContext context) { + public void actionPerformed(ListingActionContext context) { showDialog(context); } + @Override protected boolean isEnabledForContext(ListingActionContext context) { - return (context.hasSelection() && context.getSelection().getInteriorSelection() == null); + return (context.hasSelection() && + context.getSelection().getInteriorSelection() == null); } }; refAction.setHelpLocation(new HelpLocation(HelpTopics.REFERENCES, refAction.getName())); - refAction.setPopupMenuData( - new MenuData( new String[] {"References", "Create Offset References..." },null,"references" ) ); - - + refAction.setPopupMenuData(new MenuData( + new String[] { "References", "Create Offset References..." }, null, "references")); tool.addAction(refAction); } @@ -99,32 +97,33 @@ public class OffsetTablePlugin extends Plugin { private void showDialog(ListingActionContext context) { tool.setStatusInfo(""); if (containsInstructions(context)) { - tool.setStatusInfo( - "Cannot create offset references: selection contains instructions", + tool.setStatusInfo("Cannot create offset references: selection contains instructions", true); return; } AddressFactory addressFactory = context.getProgram().getAddressFactory(); Address minAddress = context.getSelection().getMinAddress(); - + OffsetTableDialog dialog = new OffsetTableDialog(minAddress, addressFactory); dialog.setSelectedSize(lastSelectedSize); dialog.setSigned(lastSigned); try { dialog.showDialog(tool); - } catch (CancelledException e) { + } + catch (CancelledException e) { return; } Address addr = dialog.getBaseAddress(); boolean signed = dialog.isSigned(); - + if (addr != null) { createOffsetTable(context, addr, dialog.getSelectedSize(), signed); } } + DataType getDataType(int size) { - switch (size) { - case 1: + switch (size) { + case 1: return new ByteDataType(); case 2: return new WordDataType(); @@ -135,18 +134,18 @@ public class OffsetTablePlugin extends Plugin { } return new WordDataType(); } - - private void createOffsetTable(ListingActionContext context, Address baseAddr, - int dataTypeSize, boolean signed) { - + + private void createOffsetTable(ListingActionContext context, Address baseAddr, int dataTypeSize, + boolean signed) { + Program program = context.getProgram(); ProgramSelection selection = context.getSelection(); lastSelectedSize = dataTypeSize; lastSigned = signed; - + DataType dt = getDataType(dataTypeSize); - - CompoundCmd cmd = new CompoundCmd("Create Offset References"); + + CompoundCmd cmd = new CompoundCmd<>("Create Offset References"); // clear the selection AddressRangeIterator rangeIter = selection.getAddressRanges(); while (rangeIter.hasNext()) { @@ -159,44 +158,48 @@ public class OffsetTablePlugin extends Plugin { while (rangeIter.hasNext()) { AddressRange range = rangeIter.next(); Address addr = range.getMinAddress(); - Address endAddr = addr.add(dataTypeSize-1); - - while(range.contains(endAddr)) { + Address endAddr = addr.add(dataTypeSize - 1); + + while (range.contains(endAddr)) { cmd.add(new MyCreateDataCmd(addr, baseAddr, dt, signed)); addr = addr.add(dataTypeSize); - endAddr = addr.add(dataTypeSize-1); + endAddr = addr.add(dataTypeSize - 1); } - } + } tool.execute(cmd, program); } catch (AddressOutOfBoundsException e) { - tool.setStatusInfo("Unable to create offset table: "+e); + tool.setStatusInfo("Unable to create offset table: " + e); } } - + private boolean containsInstructions(ListingActionContext context) { Program program = context.getProgram(); ProgramSelection selection = context.getSelection(); InstructionIterator iter = program.getListing().getInstructions(selection, true); return iter.hasNext(); } - - private class ClearCmd implements Command { + + private class ClearCmd implements Command { private AddressRange range; - + ClearCmd(AddressRange range) { this.range = range; } - - public boolean applyTo(DomainObject obj) { - Program program = (Program)obj; - program.getListing().clearCodeUnits(range.getMinAddress(), - range.getMaxAddress(), false); - return true; + + @Override + public boolean applyTo(Program program) { + program.getListing() + .clearCodeUnits(range.getMinAddress(), range.getMaxAddress(), false); + return true; } + + @Override public String getName() { return "Clear Code Units"; } + + @Override public String getStatusMsg() { return null; } @@ -207,39 +210,35 @@ public class OffsetTablePlugin extends Plugin { private Address baseAddr; private String msg; private boolean signed; - + MyCreateDataCmd(Address dataAddr, Address baseAddr, DataType dt, boolean signed) { super(dataAddr, dt); this.dataAddr = dataAddr; this.baseAddr = baseAddr; this.signed = signed; } - - /* (non Javadoc) - * @see ghidra.framework.cmd.Command#applyTo(ghidra.framework.model.DomainObject) - */ + @Override - public boolean applyTo(DomainObject obj) { - if (super.applyTo(obj)) { - Program program = (Program)obj; + public boolean applyTo(Program program) { + if (super.applyTo(program)) { ReferenceManager refManager = program.getReferenceManager(); Data data = program.getListing().getDefinedDataAt(dataAddr); if (data != null) { - Scalar value = (Scalar)data.getValue(); + Scalar value = (Scalar) data.getValue(); long offset = signed ? value.getSignedValue() : value.getUnsignedValue(); try { - data.addValueReference(baseAddr.add(offset), RefType.DATA); - } catch (AddressOutOfBoundsException e) { + data.addValueReference(baseAddr.add(offset), RefType.DATA); + } + catch (AddressOutOfBoundsException e) { msg = e.getMessage(); return false; } - Reference primRef = - refManager.getPrimaryReferenceFrom(dataAddr, 0); + Reference primRef = refManager.getPrimaryReferenceFrom(dataAddr, 0); if (primRef == null) { - Reference[] refs = data.getValueReferences(); + Reference[] refs = data.getValueReferences(); refManager.setPrimary(refs[0], true); } - return true; + return true; } msg = "Data does not exist at " + dataAddr; } @@ -250,7 +249,7 @@ public class OffsetTablePlugin extends Plugin { * @see ghidra.framework.cmd.Command#getStatusMsg() */ @Override - public String getStatusMsg() { + public String getStatusMsg() { if (msg != null) { return msg; } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/reloc/RelocationFixupCommand.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/reloc/RelocationFixupCommand.java index 305c46450d..400f71a51e 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/reloc/RelocationFixupCommand.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/reloc/RelocationFixupCommand.java @@ -1,6 +1,5 @@ /* ### * IP: GHIDRA - * REVIEWED: YES * NOTE: Refernence typo is being perpetuated * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -17,8 +16,9 @@ */ package ghidra.app.plugin.core.reloc; +import java.util.Iterator; + import ghidra.framework.cmd.BackgroundCommand; -import ghidra.framework.model.DomainObject; import ghidra.program.model.address.Address; import ghidra.program.model.listing.*; import ghidra.program.model.mem.MemoryAccessException; @@ -28,9 +28,7 @@ import ghidra.program.model.util.CodeUnitInsertionException; import ghidra.util.Msg; import ghidra.util.task.TaskMonitor; -import java.util.Iterator; - -public class RelocationFixupCommand extends BackgroundCommand { +public class RelocationFixupCommand extends BackgroundCommand { private RelocationFixupHandler relocationHandler; private RelocationFixupHandler genericHandler; private Address oldImageBase; @@ -47,8 +45,8 @@ public class RelocationFixupCommand extends BackgroundCommand { } @Override - public boolean applyTo(DomainObject obj, TaskMonitor monitor) { - Program program = (Program) obj; + public boolean applyTo(Program program, TaskMonitor monitor) { + RelocationTable relocationTable = program.getRelocationTable(); Iterator iterator = relocationTable.getRelocations(); @@ -68,12 +66,9 @@ public class RelocationFixupCommand extends BackgroundCommand { } if (hasUnhandledRelocations) { - Msg.showError( - this, - null, - "Unhandled Relocation Fixups", - "One or more relocation fix-ups were not handled for the image rebase.\n" - + "Bookmarks were created with the category \"Unhandled Image Base Relocation Fixup\""); + Msg.showError(this, null, "Unhandled Relocation Fixups", + "One or more relocation fix-ups were not handled for the image rebase.\n" + + "Bookmarks were created with the category \"Unhandled Image Base Relocation Fixup\""); } return true; diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/debug/propertymanager/PropertyDeleteCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/debug/propertymanager/PropertyDeleteCmd.java index be32a4aae5..0115676a27 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/debug/propertymanager/PropertyDeleteCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/debug/propertymanager/PropertyDeleteCmd.java @@ -1,6 +1,5 @@ /* ### * IP: GHIDRA - * REVIEWED: YES * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,7 +16,6 @@ package ghidra.app.plugin.debug.propertymanager; import ghidra.framework.cmd.Command; -import ghidra.framework.model.DomainObject; import ghidra.program.model.address.*; import ghidra.program.model.listing.Program; import ghidra.program.model.util.PropertyMap; @@ -26,12 +24,12 @@ import ghidra.program.model.util.PropertyMapManager; /** * PropertyDeletedCmd */ -class PropertyDeleteCmd implements Command { - +class PropertyDeleteCmd implements Command { + private String propName; private AddressSetView restrictedView; private String cmdName; - + /** * Construct command for deleting program properties * @param propName property name @@ -43,32 +41,27 @@ class PropertyDeleteCmd implements Command { this.restrictedView = restrictedView; this.cmdName = "Delete " + propName + " Properties"; } - + + @Override public String getName() { return cmdName; } - /** - * @see ghidra.framework.cmd.Command#applyTo(ghidra.framework.plugintool.PluginTool, ghidra.framework.model.DomainObject) - */ - public boolean applyTo(DomainObject obj) { - - if (!(obj instanceof Program)) { - throw new IllegalArgumentException("Program expected"); - } - Program program = (Program)obj; + @Override + public boolean applyTo(Program program) { + PropertyMapManager propMgr = program.getUsrPropertyManager(); - + if (restrictedView != null && !restrictedView.isEmpty()) { - PropertyMap map = propMgr.getPropertyMap(propName); + PropertyMap map = propMgr.getPropertyMap(propName); AddressRangeIterator ranges = restrictedView.getAddressRanges(); while (ranges.hasNext()) { AddressRange range = ranges.next(); - map.removeRange(range.getMinAddress(), range.getMaxAddress()); + map.removeRange(range.getMinAddress(), range.getMaxAddress()); } } else { - propMgr.removePropertyMap(propName); + propMgr.removePropertyMap(propName); } return true; } @@ -76,6 +69,7 @@ class PropertyDeleteCmd implements Command { /** * @see ghidra.framework.cmd.Command#getStatusMsg() */ + @Override public String getStatusMsg() { return null; } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/script/GhidraScript.java b/Ghidra/Features/Base/src/main/java/ghidra/app/script/GhidraScript.java index 605edbd772..9a6d825c21 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/script/GhidraScript.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/script/GhidraScript.java @@ -882,7 +882,7 @@ public abstract class GhidraScript extends FlatProgramAPI { * @param cmd the command to run * @return true if the command successfully ran */ - public final boolean runCommand(Command cmd) { + public final boolean runCommand(Command cmd) { return cmd.applyTo(currentProgram); } @@ -893,7 +893,7 @@ public abstract class GhidraScript extends FlatProgramAPI { * @param cmd the background command to run * @return true if the background command successfully ran */ - public final boolean runCommand(BackgroundCommand cmd) { + public final boolean runCommand(BackgroundCommand cmd) { return cmd.applyTo(currentProgram, monitor); } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/test/AbstractGhidraHeadlessIntegrationTest.java b/Ghidra/Features/Base/src/main/java/ghidra/test/AbstractGhidraHeadlessIntegrationTest.java index aeec07adb2..b716b5ccaa 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/test/AbstractGhidraHeadlessIntegrationTest.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/test/AbstractGhidraHeadlessIntegrationTest.java @@ -32,7 +32,7 @@ import ghidra.app.script.GhidraScriptConstants; import ghidra.app.services.GoToService; import ghidra.framework.*; import ghidra.framework.cmd.Command; -import ghidra.framework.model.UndoableDomainObject; +import ghidra.framework.model.DomainObject; import ghidra.framework.plugintool.Plugin; import ghidra.framework.plugintool.PluginTool; import ghidra.framework.plugintool.mgr.ServiceManager; @@ -307,7 +307,7 @@ public abstract class AbstractGhidraHeadlessIntegrationTest extends AbstractDock * @param wait if true, wait for undo to fully complete in Swing thread. If a modal dialog may * result from this undo, wait should be set false. */ - public static void undo(UndoableDomainObject dobj, boolean wait) { + public static void undo(DomainObject dobj, boolean wait) { Runnable r = () -> { try { dobj.undo(); @@ -331,7 +331,7 @@ public abstract class AbstractGhidraHeadlessIntegrationTest extends AbstractDock * @param wait if true, wait for redo to fully complete in Swing thread. If a modal dialog may * result from this redo, wait should be set false. */ - public static void redo(UndoableDomainObject dobj, boolean wait) { + public static void redo(DomainObject dobj, boolean wait) { Runnable r = () -> { try { dobj.redo(); @@ -356,7 +356,7 @@ public abstract class AbstractGhidraHeadlessIntegrationTest extends AbstractDock * @param dobj The domain object upon which to perform the undo. * @param name the name of the undo item on the stack. */ - public static void undo(UndoableDomainObject dobj, String name) { + public static void undo(DomainObject dobj, String name) { List names = dobj.getAllUndoNames(); int i = 0; @@ -381,7 +381,7 @@ public abstract class AbstractGhidraHeadlessIntegrationTest extends AbstractDock * * @param dobj The domain object upon which to perform the undo. */ - public static void undo(UndoableDomainObject dobj) { + public static void undo(DomainObject dobj) { undo(dobj, true); } @@ -390,7 +390,7 @@ public abstract class AbstractGhidraHeadlessIntegrationTest extends AbstractDock * * @param dobj The domain object upon which to perform the redo. */ - public static void redo(UndoableDomainObject dobj) { + public static void redo(DomainObject dobj) { redo(dobj, true); } @@ -401,7 +401,7 @@ public abstract class AbstractGhidraHeadlessIntegrationTest extends AbstractDock * @param dobj The domain object upon which to perform the undo. * @param count number of transactions to undo */ - public static void undo(UndoableDomainObject dobj, int count) { + public static void undo(DomainObject dobj, int count) { for (int i = 0; i < count; ++i) { undo(dobj); } @@ -414,7 +414,7 @@ public abstract class AbstractGhidraHeadlessIntegrationTest extends AbstractDock * @param dobj The domain object upon which to perform the redo. * @param count number of transactions to redo */ - public static void redo(UndoableDomainObject dobj, int count) { + public static void redo(DomainObject dobj, int count) { for (int i = 0; i < count; ++i) { redo(dobj); } @@ -422,9 +422,7 @@ public abstract class AbstractGhidraHeadlessIntegrationTest extends AbstractDock public static T getPlugin(PluginTool tool, Class c) { List list = tool.getManagedPlugins(); - Iterator it = list.iterator(); - while (it.hasNext()) { - Plugin p = it.next(); + for (Plugin p : list) { if (p.getClass() == c) { return c.cast(p); } diff --git a/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/AutoAnalysisWorkerTest.java b/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/AutoAnalysisWorkerTest.java index 67e794ff9d..c4f78d1904 100644 --- a/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/AutoAnalysisWorkerTest.java +++ b/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/AutoAnalysisWorkerTest.java @@ -29,7 +29,6 @@ import ghidra.app.plugin.core.disassembler.DisassemblerPlugin; import ghidra.app.plugin.core.navigation.NextPrevAddressPlugin; import ghidra.app.services.ProgramManager; import ghidra.framework.cmd.BackgroundCommand; -import ghidra.framework.model.DomainObject; import ghidra.framework.options.Options; import ghidra.framework.plugintool.PluginTool; import ghidra.program.model.address.Address; @@ -421,12 +420,12 @@ public class AutoAnalysisWorkerTest extends AbstractGhidraHeadedIntegrationTest } } - private void schedule(AutoAnalysisManager mgr, BackgroundCommand cmd, int priority) { + private void schedule(AutoAnalysisManager mgr, BackgroundCommand cmd, int priority) { invokeInstanceMethod("schedule", mgr, new Class[] { BackgroundCommand.class, int.class }, new Object[] { cmd, priority }); } - private class SetTestPropertyCommand extends BackgroundCommand { + private static class SetTestPropertyCommand extends BackgroundCommand { private final String property; private final long delay; @@ -437,7 +436,7 @@ public class AutoAnalysisWorkerTest extends AbstractGhidraHeadedIntegrationTest } @Override - public boolean applyTo(DomainObject obj, TaskMonitor monitor) { + public boolean applyTo(Program p, TaskMonitor monitor) { try { Thread.sleep(delay); } @@ -445,14 +444,13 @@ public class AutoAnalysisWorkerTest extends AbstractGhidraHeadedIntegrationTest Assert.fail();// should never happen } - Program p = (Program) obj; Options list = p.getOptions("TEST"); list.setBoolean(property, true); return true; } } - private class WorkerBackgroundTestCmd extends BackgroundCommand { + private class WorkerBackgroundTestCmd extends BackgroundCommand { private final boolean analyzeChanges; private volatile boolean isFinished = false; @@ -464,11 +462,10 @@ public class AutoAnalysisWorkerTest extends AbstractGhidraHeadedIntegrationTest } @Override - public boolean applyTo(DomainObject obj, TaskMonitor monitor) { - AutoAnalysisManager mgr = AutoAnalysisManager.getAnalysisManager((Program) obj); + public boolean applyTo(Program p, TaskMonitor monitor) { + AutoAnalysisManager mgr = AutoAnalysisManager.getAnalysisManager(p); try { - return mgr.scheduleWorker(worker, null, analyzeChanges, - TaskMonitor.DUMMY); + return mgr.scheduleWorker(worker, null, analyzeChanges, TaskMonitor.DUMMY); } catch (Exception e) { error = e; diff --git a/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/equate/EquateTablePluginTest.java b/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/equate/EquateTablePluginTest.java index b627b3cf15..d2e396039f 100644 --- a/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/equate/EquateTablePluginTest.java +++ b/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/equate/EquateTablePluginTest.java @@ -223,7 +223,7 @@ public class EquateTablePluginTest extends AbstractGhidraHeadedIntegrationTest { assertEquals("1", value); int rowCount = equatesModel.getRowCount(); - tool.execute(new RemoveEquateCmd(eq.getName(), tool), program); + tool.execute(new RemoveEquateCmd(eq.getName()), program); waitForProgram(program); waitForSwing(); diff --git a/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/function/Function1Test.java b/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/function/Function1Test.java index f1b759d2af..1947e04a09 100644 --- a/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/function/Function1Test.java +++ b/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/function/Function1Test.java @@ -531,6 +531,8 @@ public class Function1Test extends AbstractGhidraHeadedIntegrationTest { JTextArea textArea = findComponent(vcd, JTextArea.class); triggerText(textArea, "My New Comment"); pressButtonByText(vcd.getComponent(), "OK"); + waitForBusyTool(tool); + assertTrue(cb.goToField(addr("0x1006420"), "Variable Comment", 0, 0, 0)); assertEquals("My New Comment", cb.getCurrentFieldText()); assertTrue(deleteComment.isEnabledForContext(cb.getProvider().getActionContext(null))); @@ -540,6 +542,8 @@ public class Function1Test extends AbstractGhidraHeadedIntegrationTest { textArea = findComponent(vcd, JTextArea.class); triggerText(textArea, "more stuff"); pressButtonByText(vcd.getComponent(), "OK"); + waitForBusyTool(tool); + assertTrue(cb.goToField(addr("0x1006420"), "Variable Comment", 0, 0, 0)); assertEquals("more stuff", cb.getCurrentFieldText()); undo(program, "Set Variable Comment"); @@ -790,7 +794,7 @@ public class Function1Test extends AbstractGhidraHeadedIntegrationTest { Function function = program.getListing().getFunctionAt(addr("0x100248f")); assertNotNull(function);// function created by FunctionStartAnalyzer - CompoundCmd cmd = new CompoundCmd("test"); + CompoundCmd cmd = new CompoundCmd<>("test"); for (Parameter parm : function.getParameters()) { cmd.add(new DeleteVariableCmd(parm)); } @@ -887,8 +891,7 @@ public class Function1Test extends AbstractGhidraHeadedIntegrationTest { Variable[] vars = function.getLocalVariables(VariableFilter.STACK_VARIABLE_FILTER); tx(program, () -> { DataType byteDT = program.getDataTypeManager() - .addDataType(new ByteDataType(), - DataTypeConflictHandler.DEFAULT_HANDLER); + .addDataType(new ByteDataType(), DataTypeConflictHandler.DEFAULT_HANDLER); vars[1].setDataType(byteDT, SourceType.ANALYSIS); }); @@ -1050,6 +1053,7 @@ public class Function1Test extends AbstractGhidraHeadedIntegrationTest { runSwing(() -> editorField.setText("fred")); pressButtonByText(dialog, "OK"); + waitForBusyTool(); assertEquals("fred", cb.getCurrentFieldText()); undo(program, "Edit Label"); @@ -1077,6 +1081,7 @@ public class Function1Test extends AbstractGhidraHeadedIntegrationTest { pressButtonByText(dialog, "OK"); waitForBusyTool(); + assertEquals("dword ptr [EBP + bob],0x0", cb.getCurrentFieldText()); undo(program, "Edit Label"); cb.updateNow(); @@ -1486,8 +1491,8 @@ public class Function1Test extends AbstractGhidraHeadedIntegrationTest { } private void waitForBusyTool() { - waitForBusyTool(tool); program.flushEvents(); + waitForBusyTool(tool); waitForSwing(); cb.updateNow(); } @@ -1495,9 +1500,7 @@ public class Function1Test extends AbstractGhidraHeadedIntegrationTest { private void doCycleAction(DockingActionIf action) { assertTrue(action.isEnabledForContext(cb.getProvider().getActionContext(null))); performAction(action, cb.getProvider(), true); - program.flushEvents(); - waitForSwing(); - cb.updateNow(); + waitForBusyTool(); } private Function createFunctionAtEntry() { diff --git a/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/memory/MemoryMapPluginTest.java b/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/memory/MemoryMapPluginTest.java index c135dfa330..132e1341c5 100644 --- a/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/memory/MemoryMapPluginTest.java +++ b/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/memory/MemoryMapPluginTest.java @@ -220,6 +220,7 @@ public class MemoryMapPluginTest extends AbstractGhidraHeadedIntegrationTest { MemoryBlock[] blocks = memory.getBlocks(); tool.execute(new AddInitializedMemoryBlockCmd(".test", "comments", "test", getAddr(0), 0x100, true, true, true, false, (byte) 1, false), program); + waitForBusyTool(tool); JTable table = provider.getTable(); assertEquals(".test", table.getModel().getValueAt(0, MemoryMapModel.NAME)); @@ -233,6 +234,7 @@ public class MemoryMapPluginTest extends AbstractGhidraHeadedIntegrationTest { tool.execute( new DeleteBlockCmd(new Address[] { blocks[blocks.length - 1].getStart() }, null), program); + waitForBusyTool(tool); JTable table = provider.getTable(); assertEquals(blocks.length - 1, table.getModel().getRowCount()); @@ -261,6 +263,7 @@ public class MemoryMapPluginTest extends AbstractGhidraHeadedIntegrationTest { MemoryBlock[] blocks = memory.getBlocks(); tool.execute(new AddUninitializedMemoryBlockCmd(".test", "comments", "test", getAddr(0), 0x100, true, true, true, false, false), program); + waitForBusyTool(tool); JTable table = provider.getTable(); assertEquals(blocks.length + 1, table.getModel().getRowCount()); assertEquals(".test", table.getModel().getValueAt(0, MemoryMapModel.NAME)); @@ -281,6 +284,7 @@ public class MemoryMapPluginTest extends AbstractGhidraHeadedIntegrationTest { MemoryBlock[] blocks = memory.getBlocks(); tool.execute(new AddInitializedMemoryBlockCmd(".test", "comments", "test", getAddr(0), 0x100, true, true, true, false, (byte) 1, false), program); + waitForBusyTool(tool); JTable table = provider.getTable(); assertEquals(blocks.length + 1, table.getModel().getRowCount()); diff --git a/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/memory/MemoryMapProvider3Test.java b/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/memory/MemoryMapProvider3Test.java index ff31f1d8e0..1b6c087164 100644 --- a/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/memory/MemoryMapProvider3Test.java +++ b/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/memory/MemoryMapProvider3Test.java @@ -162,6 +162,7 @@ public class MemoryMapProvider3Test extends AbstractGhidraHeadedIntegrationTest DockingActionIf action = getAction(plugin, "Split Block"); performAction(action, false); + waitForBusyTool(tool); // find the dialog for the add SplitBlockDialog d = waitForDialogComponent(SplitBlockDialog.class); @@ -535,7 +536,7 @@ public class MemoryMapProvider3Test extends AbstractGhidraHeadedIntegrationTest assertTrue(okButton.isEnabled()); runSwing(() -> okButton.getActionListeners()[0].actionPerformed(null)); - waitForSwing(); + waitForBusyTool(tool); assertEquals(".text", model.getValueAt(0, MemoryMapModel.NAME)); assertEquals("00002000", model.getValueAt(0, MemoryMapModel.START)); @@ -543,12 +544,16 @@ public class MemoryMapProvider3Test extends AbstractGhidraHeadedIntegrationTest assertEquals("0x1005600", model.getValueAt(0, MemoryMapModel.LENGTH)); undo(program); + waitForBusyTool(tool); + assertEquals(".text", model.getValueAt(0, MemoryMapModel.NAME)); assertEquals("01001000", model.getValueAt(0, MemoryMapModel.START)); assertEquals("010075ff", model.getValueAt(0, MemoryMapModel.END)); assertEquals("0x6600", model.getValueAt(0, MemoryMapModel.LENGTH)); redo(program); + waitForBusyTool(tool); + assertEquals(".text", model.getValueAt(0, MemoryMapModel.NAME)); assertEquals("00002000", model.getValueAt(0, MemoryMapModel.START)); assertEquals("010075ff", model.getValueAt(0, MemoryMapModel.END)); @@ -605,7 +610,8 @@ public class MemoryMapProvider3Test extends AbstractGhidraHeadedIntegrationTest assertTrue(okButton.isEnabled()); runSwing(() -> okButton.getActionListeners()[0].actionPerformed(null)); - waitForSwing(); + + waitForBusyTool(tool); assertEquals(".text", model.getValueAt(0, MemoryMapModel.NAME)); assertEquals("01000000", model.getValueAt(0, MemoryMapModel.START)); @@ -613,12 +619,16 @@ public class MemoryMapProvider3Test extends AbstractGhidraHeadedIntegrationTest assertEquals("0x7600", model.getValueAt(0, MemoryMapModel.LENGTH)); undo(program); + waitForBusyTool(tool); + assertEquals(".text", model.getValueAt(0, MemoryMapModel.NAME)); assertEquals("01001000", model.getValueAt(0, MemoryMapModel.START)); assertEquals("010075ff", model.getValueAt(0, MemoryMapModel.END)); assertEquals("0x6600", model.getValueAt(0, MemoryMapModel.LENGTH)); redo(program); + waitForBusyTool(tool); + assertEquals(".text", model.getValueAt(0, MemoryMapModel.NAME)); assertEquals("01000000", model.getValueAt(0, MemoryMapModel.START)); assertEquals("010075ff", model.getValueAt(0, MemoryMapModel.END)); @@ -735,7 +745,8 @@ public class MemoryMapProvider3Test extends AbstractGhidraHeadedIntegrationTest assertTrue(okButton.isEnabled()); runSwing(() -> okButton.getActionListeners()[0].actionPerformed(null)); - waitForSwing(); + + waitForBusyTool(tool); assertEquals(".text", model.getValueAt(0, MemoryMapModel.NAME)); assertEquals("01001000", model.getValueAt(0, MemoryMapModel.START)); @@ -749,6 +760,7 @@ public class MemoryMapProvider3Test extends AbstractGhidraHeadedIntegrationTest DockingActionIf action = getAction(plugin, "Expand Block Down"); performAction(action, false); + waitForBusyTool(tool); // find the dialog for the add ExpandBlockDialog d = waitForDialogComponent(ExpandBlockDialog.class); @@ -762,7 +774,8 @@ public class MemoryMapProvider3Test extends AbstractGhidraHeadedIntegrationTest assertTrue(okButton.isEnabled()); runSwing(() -> okButton.getActionListeners()[0].actionPerformed(null)); - waitForSwing(); + + waitForBusyTool(tool); assertEquals(".text", model.getValueAt(0, MemoryMapModel.NAME)); assertEquals("01001000", model.getValueAt(0, MemoryMapModel.START)); diff --git a/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/programtree/ProgramTreePlugin1Test.java b/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/programtree/ProgramTreePlugin1Test.java index 0287766aba..a09aa83329 100644 --- a/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/programtree/ProgramTreePlugin1Test.java +++ b/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/programtree/ProgramTreePlugin1Test.java @@ -222,9 +222,8 @@ public class ProgramTreePlugin1Test extends AbstractProgramTreePluginTest { DockingActionIf createFolderAction = getAction("Create Folder"); performAction(createFolderAction, getActionContext(), true); - waitForProgram(program); - setEditorText("test1"); + waitForBusyTool(tool); String currentText = setEditorText("test1"); assertEquals(newName, currentText); @@ -258,7 +257,8 @@ public class ProgramTreePlugin1Test extends AbstractProgramTreePluginTest { DockingActionIf createFragmentAction = getAction("Create Fragment"); performAction(createFragmentAction, getActionContext(), true); - waitForProgram(program); + + waitForBusyTool(tool); String currentText = setEditorText("test1"); assertEquals(newName, currentText); @@ -633,8 +633,7 @@ public class ProgramTreePlugin1Test extends AbstractProgramTreePluginTest { int row = getRowForPath(nodes[0].getTreePath()); Component comp = getCellRendererComponentForLeaf(nodes[0], row); - assertEquals(new GIcon(DnDTreeCellRenderer.VIEWED_FRAGMENT), - ((JLabel) comp).getIcon()); + assertEquals(new GIcon(DnDTreeCellRenderer.VIEWED_FRAGMENT), ((JLabel) comp).getIcon()); } @Test @@ -676,26 +675,22 @@ public class ProgramTreePlugin1Test extends AbstractProgramTreePluginTest { int row = getRowForPath(node.getTreePath()); Component comp = getCellRendererComponentForLeaf(node, row); - assertEquals(new GIcon(DnDTreeCellRenderer.VIEWED_FRAGMENT), - ((JLabel) comp).getIcon()); + assertEquals(new GIcon(DnDTreeCellRenderer.VIEWED_FRAGMENT), ((JLabel) comp).getIcon()); row = getRowForPath(n2.getTreePath()); comp = getCellRendererComponentForLeaf(n2, row); - assertEquals(new GIcon(DnDTreeCellRenderer.VIEWED_FRAGMENT), - ((JLabel) comp).getIcon()); + assertEquals(new GIcon(DnDTreeCellRenderer.VIEWED_FRAGMENT), ((JLabel) comp).getIcon()); setSelectionPaths(new TreePath[] { n2.getTreePath() }); setViewPaths(getSelectionPaths()); row = getRowForPath(n2.getTreePath()); comp = getCellRendererComponentForLeaf(n2, row); - assertEquals(new GIcon(DnDTreeCellRenderer.VIEWED_FRAGMENT), - ((JLabel) comp).getIcon()); + assertEquals(new GIcon(DnDTreeCellRenderer.VIEWED_FRAGMENT), ((JLabel) comp).getIcon()); row = getRowForPath(node.getTreePath()); getCellRendererComponentForLeaf(node, row); - assertEquals(new GIcon(DnDTreeCellRenderer.FRAGMENT), - ((JLabel) comp).getIcon()); + assertEquals(new GIcon(DnDTreeCellRenderer.FRAGMENT), ((JLabel) comp).getIcon()); } @@ -737,8 +732,7 @@ public class ProgramTreePlugin1Test extends AbstractProgramTreePluginTest { int row = getRowForPath(node.getTreePath()); Component comp = tree.getCellRenderer() .getTreeCellRendererComponent(tree, node, true, false, true, row, false); - assertEquals(new GIcon(DnDTreeCellRenderer.CLOSED_FOLDER), - ((JLabel) comp).getIcon()); + assertEquals(new GIcon(DnDTreeCellRenderer.CLOSED_FOLDER), ((JLabel) comp).getIcon()); } @Test diff --git a/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/programtree/ViewManagerPluginTest.java b/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/programtree/ViewManagerPluginTest.java index 453a3d9065..5b6dfdea7b 100644 --- a/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/programtree/ViewManagerPluginTest.java +++ b/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/programtree/ViewManagerPluginTest.java @@ -239,6 +239,8 @@ public class ViewManagerPluginTest extends AbstractGhidraHeadedIntegrationTest { final DockingActionIf closeAction = getAction(plugin, "Close Tree View"); SwingUtilities.invokeAndWait(() -> closeAction.actionPerformed(new DefaultActionContext())); + waitForBusyTool(tool); + String[] treeNames = program.getListing().getTreeNames(); assertEquals(treeNames.length - 1, tabbedPane.getTabCount()); ViewProviderService vps = provider.getCurrentViewProvider(); @@ -258,7 +260,9 @@ public class ViewManagerPluginTest extends AbstractGhidraHeadedIntegrationTest { final DockingActionIf deleteAction = getAction(plugin, "Delete Tree View"); SwingUtilities .invokeAndWait(() -> deleteAction.actionPerformed(new DefaultActionContext())); - program.flushEvents(); + + waitForBusyTool(tool); + assertNull(program.getListing().getRootModule("Tree Two")); String[] treeNames = program.getListing().getTreeNames(); assertEquals(treeNames.length, tabbedPane.getTabCount()); @@ -267,6 +271,7 @@ public class ViewManagerPluginTest extends AbstractGhidraHeadedIntegrationTest { assertTrue(provider.getCurrentView().hasSameAddresses(cb.getView())); undo(program); + // Tree Two should come back assertNotNull(program.getListing().getRootModule("Tree Two")); ViewProviderService vps = provider.getCurrentViewProvider(); @@ -275,6 +280,7 @@ public class ViewManagerPluginTest extends AbstractGhidraHeadedIntegrationTest { assertTrue(provider.getCurrentView().hasSameAddresses(vps.getCurrentView())); redo(program); + assertNull(program.getListing().getRootModule("Tree Two")); treeNames = program.getListing().getTreeNames(); assertEquals(treeNames.length, tabbedPane.getTabCount()); @@ -293,30 +299,30 @@ public class ViewManagerPluginTest extends AbstractGhidraHeadedIntegrationTest { SwingUtilities .invokeAndWait(() -> deleteAction.actionPerformed(new DefaultActionContext())); - program.flushEvents(); + waitForBusyTool(tool); setCurrentViewProvider("Tree One"); SwingUtilities .invokeAndWait(() -> deleteAction.actionPerformed(new DefaultActionContext())); - program.flushEvents(); + waitForBusyTool(tool); setCurrentViewProvider("Tree Two"); SwingUtilities .invokeAndWait(() -> deleteAction.actionPerformed(new DefaultActionContext())); - program.flushEvents(); + waitForBusyTool(tool); setCurrentViewProvider("Tree Three"); SwingUtilities .invokeAndWait(() -> deleteAction.actionPerformed(new DefaultActionContext())); - program.flushEvents(); + waitForBusyTool(tool); // attempt to delete the last view SwingUtilities .invokeAndWait(() -> deleteAction.actionPerformed(new DefaultActionContext())); - program.flushEvents(); + waitForBusyTool(tool); ViewProviderService vps = provider.getCurrentViewProvider(); assertEquals(DEFAULT_TREE_NAME, vps.getViewName()); diff --git a/Ghidra/Features/Base/src/test.slow/java/ghidra/framework/project/tool/CloseToolTest.java b/Ghidra/Features/Base/src/test.slow/java/ghidra/framework/project/tool/CloseToolTest.java index 0945a9ce12..e149bf5965 100644 --- a/Ghidra/Features/Base/src/test.slow/java/ghidra/framework/project/tool/CloseToolTest.java +++ b/Ghidra/Features/Base/src/test.slow/java/ghidra/framework/project/tool/CloseToolTest.java @@ -213,7 +213,7 @@ public class CloseToolTest extends AbstractGhidraHeadedIntegrationTest { // Inner Classes //================================================================================================== - private class ControllableBackgroundCommand extends BackgroundCommand { + private static class ControllableBackgroundCommand extends BackgroundCommand { private volatile boolean hasStarted; private volatile boolean stop; diff --git a/Ghidra/Features/Base/src/test.slow/java/ghidra/program/database/mem/MemoryManagerTest.java b/Ghidra/Features/Base/src/test.slow/java/ghidra/program/database/mem/MemoryManagerTest.java index 7bbaa46fff..e24a7b8f06 100644 --- a/Ghidra/Features/Base/src/test.slow/java/ghidra/program/database/mem/MemoryManagerTest.java +++ b/Ghidra/Features/Base/src/test.slow/java/ghidra/program/database/mem/MemoryManagerTest.java @@ -674,7 +674,7 @@ public class MemoryManagerTest extends AbstractGhidraHeadedIntegrationTest { data = program.getListing().getDataAt(addr(1001)); assertEquals("byte", data.getDataType().getName()); - UninitializedBlockCmd cmd = new UninitializedBlockCmd(program, block); + UninitializedBlockCmd cmd = new UninitializedBlockCmd(block); cmd.applyTo(program); assertNotNull(block); diff --git a/Ghidra/Features/Base/src/test/java/ghidra/framework/plugintool/mgr/BackgroundCommandTaskTest.java b/Ghidra/Features/Base/src/test/java/ghidra/framework/plugintool/mgr/BackgroundCommandTaskTest.java index 0c539d6c62..9ebb30d6f3 100644 --- a/Ghidra/Features/Base/src/test/java/ghidra/framework/plugintool/mgr/BackgroundCommandTaskTest.java +++ b/Ghidra/Features/Base/src/test/java/ghidra/framework/plugintool/mgr/BackgroundCommandTaskTest.java @@ -134,7 +134,7 @@ public class BackgroundCommandTaskTest extends AbstractGenericTest { } } - private class SuccessfulDummyCommand extends BackgroundCommand { + private class SuccessfulDummyCommand extends BackgroundCommand { SuccessfulDummyCommand() { super("Dummy", true, true, false); @@ -147,7 +147,7 @@ public class BackgroundCommandTaskTest extends AbstractGenericTest { } - private class NullPointerExceptionCommand extends BackgroundCommand { + private class NullPointerExceptionCommand extends BackgroundCommand { NullPointerExceptionCommand() { super("Dummy", true, true, false); @@ -160,7 +160,7 @@ public class BackgroundCommandTaskTest extends AbstractGenericTest { } - private class RollbackExceptionCommand extends BackgroundCommand { + private class RollbackExceptionCommand extends BackgroundCommand { RollbackExceptionCommand() { super("Dummy", true, true, false); } @@ -171,7 +171,7 @@ public class BackgroundCommandTaskTest extends AbstractGenericTest { } } - private class DomainObjectLockedExceptionCommand extends BackgroundCommand { + private class DomainObjectLockedExceptionCommand extends BackgroundCommand { DomainObjectLockedExceptionCommand() { super("Dummy", true, true, false); } diff --git a/Ghidra/Features/Decompiler/src/main/java/ghidra/app/cmd/function/DecompilerParallelConventionAnalysisCmd.java b/Ghidra/Features/Decompiler/src/main/java/ghidra/app/cmd/function/DecompilerParallelConventionAnalysisCmd.java index e45d70a1eb..23e5687dcc 100644 --- a/Ghidra/Features/Decompiler/src/main/java/ghidra/app/cmd/function/DecompilerParallelConventionAnalysisCmd.java +++ b/Ghidra/Features/Decompiler/src/main/java/ghidra/app/cmd/function/DecompilerParallelConventionAnalysisCmd.java @@ -20,7 +20,6 @@ import java.io.IOException; import ghidra.app.decompiler.*; import ghidra.app.util.NamespaceUtils; import ghidra.framework.cmd.BackgroundCommand; -import ghidra.framework.model.DomainObject; import ghidra.program.model.lang.CompilerSpec; import ghidra.program.model.lang.PrototypeModel; import ghidra.program.model.listing.Function; @@ -33,7 +32,7 @@ import ghidra.util.exception.CancelledException; import ghidra.util.exception.InvalidInputException; import ghidra.util.task.TaskMonitor; -public class DecompilerParallelConventionAnalysisCmd extends BackgroundCommand { +public class DecompilerParallelConventionAnalysisCmd extends BackgroundCommand { private static final String STD_NAMESPACE = "std"; @@ -75,8 +74,8 @@ public class DecompilerParallelConventionAnalysisCmd extends BackgroundCommand { } @Override - public boolean applyTo(DomainObject obj, TaskMonitor monitor) { - program = (Program) obj; + public boolean applyTo(Program p, TaskMonitor monitor) { + program = p; try { monitor.checkCancelled(); @@ -207,8 +206,8 @@ public class DecompilerParallelConventionAnalysisCmd extends BackgroundCommand { // prevent accidental treatment of std namespace as class !parentNamespace.getName().equals(STD_NAMESPACE)) { // does it have a this call convention that is the equivalent of the stdcall - PrototypeModel callingConvention = program.getCompilerSpec().getCallingConvention( - CompilerSpec.CALLING_CONVENTION_thiscall); + PrototypeModel callingConvention = program.getCompilerSpec() + .getCallingConvention(CompilerSpec.CALLING_CONVENTION_thiscall); if (callingConvention != null) { modelName = CompilerSpec.CALLING_CONVENTION_thiscall; } diff --git a/Ghidra/Features/Decompiler/src/main/java/ghidra/app/cmd/function/DecompilerParameterIdCmd.java b/Ghidra/Features/Decompiler/src/main/java/ghidra/app/cmd/function/DecompilerParameterIdCmd.java index c5f9925ad3..25b7e3ffe2 100644 --- a/Ghidra/Features/Decompiler/src/main/java/ghidra/app/cmd/function/DecompilerParameterIdCmd.java +++ b/Ghidra/Features/Decompiler/src/main/java/ghidra/app/cmd/function/DecompilerParameterIdCmd.java @@ -25,7 +25,6 @@ import generic.concurrent.*; import ghidra.app.decompiler.*; import ghidra.app.plugin.core.analysis.AutoAnalysisManager; import ghidra.framework.cmd.BackgroundCommand; -import ghidra.framework.model.DomainObject; import ghidra.program.model.address.*; import ghidra.program.model.data.DataType; import ghidra.program.model.data.VoidDataType; @@ -41,7 +40,7 @@ import ghidra.util.exception.InvalidInputException; import ghidra.util.graph.AbstractDependencyGraph; import ghidra.util.task.TaskMonitor; -public class DecompilerParameterIdCmd extends BackgroundCommand { +public class DecompilerParameterIdCmd extends BackgroundCommand { private AddressSet entryPoints = new AddressSet(); private Program program; @@ -52,8 +51,8 @@ public class DecompilerParameterIdCmd extends BackgroundCommand { private int decompilerTimeoutSecs; public DecompilerParameterIdCmd(String name, AddressSetView entries, - SourceType sourceTypeClearLevel, - boolean commitDataTypes, boolean commitVoidReturn, int decompilerTimeoutSecs) { + SourceType sourceTypeClearLevel, boolean commitDataTypes, boolean commitVoidReturn, + int decompilerTimeoutSecs) { super(name, true, true, false); entryPoints.add(entries); this.sourceTypeClearLevel = sourceTypeClearLevel; @@ -63,11 +62,10 @@ public class DecompilerParameterIdCmd extends BackgroundCommand { } @Override - public boolean applyTo(DomainObject obj, final TaskMonitor monitor) { - program = (Program) obj; + public boolean applyTo(Program p, final TaskMonitor monitor) { + program = p; - CachingPool decompilerPool = - new CachingPool<>(new DecompilerFactory()); + CachingPool decompilerPool = new CachingPool<>(new DecompilerFactory()); QRunnable
runnable = new ParallelDecompileRunnable(decompilerPool); ConcurrentGraphQ
queue = null; @@ -163,8 +161,7 @@ public class DecompilerParameterIdCmd extends BackgroundCommand { } } catch (InvalidInputException e) { - Msg.warn(this, - "Error changing signature SourceType on " + func.getName(), e); + Msg.warn(this, "Error changing signature SourceType on " + func.getName(), e); } } } @@ -298,10 +295,7 @@ public class DecompilerParameterIdCmd extends BackgroundCommand { Address entryPoint = func.getEntryPoint(); BookmarkManager bookmarkManager = hfunc.getFunction().getProgram().getBookmarkManager(); - bookmarkManager.setBookmark( - entryPoint, - BookmarkType.WARNING, - "DecompilerParamID", + bookmarkManager.setBookmark(entryPoint, BookmarkType.WARNING, "DecompilerParamID", "Problem recovering parameters in function " + func.getName() + " at " + func.getEntryPoint() + " unknown input variable " + sym.getName()); } diff --git a/Ghidra/Features/Decompiler/src/main/java/ghidra/app/cmd/function/DecompilerSwitchAnalysisCmd.java b/Ghidra/Features/Decompiler/src/main/java/ghidra/app/cmd/function/DecompilerSwitchAnalysisCmd.java index 590c67a709..6d7ecd1534 100644 --- a/Ghidra/Features/Decompiler/src/main/java/ghidra/app/cmd/function/DecompilerSwitchAnalysisCmd.java +++ b/Ghidra/Features/Decompiler/src/main/java/ghidra/app/cmd/function/DecompilerSwitchAnalysisCmd.java @@ -23,7 +23,6 @@ import ghidra.app.decompiler.DecompileResults; import ghidra.docking.settings.SettingsDefinition; import ghidra.docking.settings.SettingsImpl; import ghidra.framework.cmd.BackgroundCommand; -import ghidra.framework.model.DomainObject; import ghidra.program.model.address.*; import ghidra.program.model.data.*; import ghidra.program.model.lang.Register; @@ -40,7 +39,7 @@ import ghidra.util.UndefinedFunction; import ghidra.util.exception.*; import ghidra.util.task.TaskMonitor; -public class DecompilerSwitchAnalysisCmd extends BackgroundCommand { +public class DecompilerSwitchAnalysisCmd extends BackgroundCommand { private static final int DEFAULT_CASE_VALUE = 0xbad1abe1; private Program program; @@ -54,8 +53,8 @@ public class DecompilerSwitchAnalysisCmd extends BackgroundCommand { } @Override - public boolean applyTo(DomainObject obj, TaskMonitor monitor) { - program = (Program) obj; + public boolean applyTo(Program p, TaskMonitor monitor) { + program = p; if (monitor.isCancelled()) { return false; diff --git a/Ghidra/Features/Decompiler/src/main/java/ghidra/app/plugin/core/decompile/actions/FillOutStructureCmd.java b/Ghidra/Features/Decompiler/src/main/java/ghidra/app/plugin/core/decompile/actions/FillOutStructureCmd.java index 3e902beda7..a90c5b3f45 100644 --- a/Ghidra/Features/Decompiler/src/main/java/ghidra/app/plugin/core/decompile/actions/FillOutStructureCmd.java +++ b/Ghidra/Features/Decompiler/src/main/java/ghidra/app/plugin/core/decompile/actions/FillOutStructureCmd.java @@ -46,6 +46,10 @@ import ghidra.util.task.TaskMonitor; */ public class FillOutStructureCmd extends BackgroundCommand { + // NOTE: (see GP-4408) This Command implementation should be refactored to break-out the + // Utility aspects which are contained within and used publicly without invoking the applyTo + // method. In addition, the Command should not be constructed with a Program instance. + /** * Varnode with data-flow traceable to original pointer */ @@ -276,10 +280,7 @@ public class FillOutStructureCmd extends BackgroundCommand { HashMap savedList = addressToCallInputMap; addressToCallInputMap = new HashMap<>(); Set
keys = savedList.keySet(); - Iterator
keyIter = keys.iterator(); - while (keyIter.hasNext()) { - Address addr = keyIter.next(); - + for (Address addr : keys) { if (doneSet.contains(addr)) { continue; } diff --git a/Ghidra/Features/FunctionID/src/main/java/ghidra/feature/fid/cmd/ApplyFidEntriesCommand.java b/Ghidra/Features/FunctionID/src/main/java/ghidra/feature/fid/cmd/ApplyFidEntriesCommand.java index 1c89a77a7f..bab3a95d2d 100644 --- a/Ghidra/Features/FunctionID/src/main/java/ghidra/feature/fid/cmd/ApplyFidEntriesCommand.java +++ b/Ghidra/Features/FunctionID/src/main/java/ghidra/feature/fid/cmd/ApplyFidEntriesCommand.java @@ -23,7 +23,6 @@ import ghidra.app.util.demangler.DemangledObject; import ghidra.feature.fid.db.FidQueryService; import ghidra.feature.fid.service.*; import ghidra.framework.cmd.BackgroundCommand; -import ghidra.framework.model.DomainObject; import ghidra.program.model.address.*; import ghidra.program.model.listing.*; import ghidra.program.model.symbol.*; @@ -31,7 +30,7 @@ import ghidra.util.Msg; import ghidra.util.exception.*; import ghidra.util.task.TaskMonitor; -public class ApplyFidEntriesCommand extends BackgroundCommand { +public class ApplyFidEntriesCommand extends BackgroundCommand { public static final String FID_CONFLICT = "FID_conflict:"; public static final String FID_BOOKMARK_CATEGORY = "Function ID Analyzer"; public static final String FIDCONFLICT_BOOKMARK_CATEGORY = "Function ID Conflict"; @@ -58,55 +57,49 @@ public class ApplyFidEntriesCommand extends BackgroundCommand { } @Override - public boolean applyTo(DomainObject obj, TaskMonitor monitor) { + public boolean applyTo(Program program, TaskMonitor monitor) { FidService service = new FidService(); - - if (obj instanceof Program) { - Program program = (Program) obj; - - if (!service.canProcess(program.getLanguage())) { - return false; - } - - try (FidQueryService fidQueryService = - service.openFidQueryService(program.getLanguage(), false)) { - - monitor.setMessage("FID Analysis"); - List processProgram = - service.processProgram(program, fidQueryService, scoreThreshold, monitor); - if (processProgram == null) { - return false; - } - - for (FidSearchResult entry : processProgram) { - monitor.checkCancelled(); - - monitor.incrementProgress(1); - if (entry.function.isThunk()) { - continue; - } - - if (!entry.matches.isEmpty()) { - processMatches(entry, program, monitor); - } - else { - Msg.trace(this, "no results for function " + entry.function.getName() + - " at " + entry.function.getEntryPoint()); - } - } - applyConflictLabels(program); - } - catch (CancelledException e) { - return false; - } - catch (VersionException | IOException e) { - setStatusMsg(e.getMessage()); - return false; - } - - return true; + if (!service.canProcess(program.getLanguage())) { + return false; } - return false; + + try (FidQueryService fidQueryService = + service.openFidQueryService(program.getLanguage(), false)) { + + monitor.setMessage("FID Analysis"); + List processProgram = + service.processProgram(program, fidQueryService, scoreThreshold, monitor); + if (processProgram == null) { + return false; + } + + for (FidSearchResult entry : processProgram) { + monitor.checkCancelled(); + + monitor.incrementProgress(1); + if (entry.function.isThunk()) { + continue; + } + + if (!entry.matches.isEmpty()) { + processMatches(entry, program, monitor); + } + else { + Msg.trace(this, "no results for function " + entry.function.getName() + " at " + + entry.function.getEntryPoint()); + } + } + applyConflictLabels(program); + } + catch (CancelledException e) { + return false; + } + catch (VersionException | IOException e) { + setStatusMsg(e.getMessage()); + return false; + } + + return true; } private void processMatches(FidSearchResult result, Program program, TaskMonitor monitor) @@ -264,8 +257,8 @@ public class ApplyFidEntriesCommand extends BackgroundCommand { if (bookmarkContents != null && !bookmarkContents.equals("")) { function.getProgram() .getBookmarkManager() - .setBookmark(function.getEntryPoint(), - BookmarkType.ANALYSIS, FID_BOOKMARK_CATEGORY, bookmarkContents); + .setBookmark(function.getEntryPoint(), BookmarkType.ANALYSIS, + FID_BOOKMARK_CATEGORY, bookmarkContents); } } @@ -376,8 +369,7 @@ public class ApplyFidEntriesCommand extends BackgroundCommand { if (createBookmarksEnabled) { BookmarkManager bookmarkManager = function.getProgram().getBookmarkManager(); bookmarkManager.setBookmark(addr, BookmarkType.ANALYSIS, - FIDCONFLICT_BOOKMARK_CATEGORY, - "Multiple likely matching functions"); + FIDCONFLICT_BOOKMARK_CATEGORY, "Multiple likely matching functions"); } } } diff --git a/Ghidra/Features/MicrosoftCodeAnalyzer/src/main/java/ghidra/app/cmd/data/AbstractCreateDataBackgroundCmd.java b/Ghidra/Features/MicrosoftCodeAnalyzer/src/main/java/ghidra/app/cmd/data/AbstractCreateDataBackgroundCmd.java index c28fa87fd9..26564e6553 100644 --- a/Ghidra/Features/MicrosoftCodeAnalyzer/src/main/java/ghidra/app/cmd/data/AbstractCreateDataBackgroundCmd.java +++ b/Ghidra/Features/MicrosoftCodeAnalyzer/src/main/java/ghidra/app/cmd/data/AbstractCreateDataBackgroundCmd.java @@ -18,7 +18,6 @@ package ghidra.app.cmd.data; import ghidra.app.util.datatype.microsoft.DataApplyOptions; import ghidra.app.util.datatype.microsoft.DataValidationOptions; import ghidra.framework.cmd.BackgroundCommand; -import ghidra.framework.model.DomainObject; import ghidra.program.model.address.Address; import ghidra.program.model.address.AddressOutOfBoundsException; import ghidra.program.model.data.*; @@ -33,9 +32,10 @@ import ghidra.util.task.TaskMonitor; /** * This is the abstract command to extend when creating a specific data type or related data type. + * @param {@link AbstractCreateDataTypeModel} implementation class */ public abstract class AbstractCreateDataBackgroundCmd - extends BackgroundCommand { + extends BackgroundCommand { protected final String name; private Address address; @@ -99,14 +99,9 @@ public abstract class AbstractCreateDataBackgroundCmd { private ProgramDiffPlugin plugin; /** * Constructor. * @param plugin - * @param currentLocation - * @param diffControl */ NextDiffCommand(ProgramDiffPlugin plugin) { super("Next Difference", false, false, true); this.plugin = plugin; } - /** - * @see ghidra.framework.cmd.BackgroundCommand#applyTo(ghidra.framework.model.DomainObject, ghidra.util.task.TaskMonitor) - */ @Override - public boolean applyTo(DomainObject obj, TaskMonitor monitor) { + public boolean applyTo(Program program, TaskMonitor monitor) { monitor.setMessage("NextDiffTask starting..."); plugin.nextDiff(); return true; diff --git a/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/api/main/VTSession.java b/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/api/main/VTSession.java index 9fa6ce990a..bce88f6f91 100644 --- a/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/api/main/VTSession.java +++ b/Ghidra/Features/VersionTracking/src/main/java/ghidra/feature/vt/api/main/VTSession.java @@ -20,15 +20,15 @@ import java.util.List; import java.util.Set; import db.util.ErrorHandler; +import ghidra.framework.model.DomainObject; import ghidra.framework.model.DomainObjectListener; -import ghidra.framework.model.UndoableDomainObject; import ghidra.program.model.listing.Program; /** * Main interface for a Version Tracking Session * */ -public interface VTSession extends ErrorHandler, UndoableDomainObject { +public interface VTSession extends ErrorHandler, DomainObject { /** * Returns the AssociationManager. diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/framework/cmd/BackgroundCommand.java b/Ghidra/Framework/Project/src/main/java/ghidra/framework/cmd/BackgroundCommand.java index c5390ab589..3f5ba9e988 100644 --- a/Ghidra/Framework/Project/src/main/java/ghidra/framework/cmd/BackgroundCommand.java +++ b/Ghidra/Framework/Project/src/main/java/ghidra/framework/cmd/BackgroundCommand.java @@ -16,6 +16,7 @@ package ghidra.framework.cmd; import ghidra.framework.model.DomainObject; +import ghidra.framework.plugintool.PluginTool; import ghidra.util.task.TaskMonitor; /** @@ -26,8 +27,10 @@ import ghidra.util.task.TaskMonitor; * *

This allows commands to make changes in the background so that the GUI is not frozen and the * user can still interact with the GUI. + * + * @param {@link DomainObject} implementation interface */ -public abstract class BackgroundCommand implements Command { +public abstract class BackgroundCommand implements Command { private String name; private boolean hasProgress; @@ -47,7 +50,7 @@ public abstract class BackgroundCommand implements Command { } @Override - public final boolean applyTo(DomainObject obj) { + public final boolean applyTo(T obj) { return applyTo(obj, TaskMonitor.DUMMY); } @@ -59,7 +62,7 @@ public abstract class BackgroundCommand implements Command { * @param monitor monitor to show progress of the command * @return true if the command applied successfully */ - public abstract boolean applyTo(DomainObject obj, TaskMonitor monitor); + public abstract boolean applyTo(T obj, TaskMonitor monitor); // TODO: This should really throw CancelledException when canceled @@ -126,4 +129,8 @@ public abstract class BackgroundCommand implements Command { public String toString() { return getName(); } + + public void run(PluginTool tool, T obj) { + tool.executeBackgroundCommand(this, obj); + } } diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/framework/cmd/BackgroundCommandListener.java b/Ghidra/Framework/Project/src/main/java/ghidra/framework/cmd/BackgroundCommandListener.java deleted file mode 100644 index 062549e4c1..0000000000 --- a/Ghidra/Framework/Project/src/main/java/ghidra/framework/cmd/BackgroundCommandListener.java +++ /dev/null @@ -1,29 +0,0 @@ -/* ### - * IP: GHIDRA - * REVIEWED: YES - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ghidra.framework.cmd; - -/** - * Listener that is notified when a BackgroundCommand completes. - */ -public interface BackgroundCommandListener { - /** - * Notification that the given BackgroundCommand has completed. - * @param cmd background command that has completed - */ - public void commandCompleted(BackgroundCommand cmd); -} - diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/framework/cmd/Command.java b/Ghidra/Framework/Project/src/main/java/ghidra/framework/cmd/Command.java index cc60f38121..581d026e48 100644 --- a/Ghidra/Framework/Project/src/main/java/ghidra/framework/cmd/Command.java +++ b/Ghidra/Framework/Project/src/main/java/ghidra/framework/cmd/Command.java @@ -1,6 +1,5 @@ /* ### * IP: GHIDRA - * REVIEWED: YES * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,8 +20,9 @@ import ghidra.framework.model.DomainObject; /** * Interface to define a change made to a domain object. * + * @param {@link DomainObject} implementation interface */ -public interface Command { +public interface Command { /** * Applies the command to the given domain object. @@ -31,8 +31,8 @@ public interface Command { * * @return true if the command applied successfully */ - public boolean applyTo(DomainObject obj); - + public boolean applyTo(T obj); + /** * Returns the status message indicating the status of the command. * @@ -40,7 +40,7 @@ public interface Command { * was successful */ public String getStatusMsg(); - + /** * Returns the name of this command. * diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/framework/cmd/CompoundBackgroundCommand.java b/Ghidra/Framework/Project/src/main/java/ghidra/framework/cmd/CompoundBackgroundCommand.java index fdfffbe717..13f2d91da5 100644 --- a/Ghidra/Framework/Project/src/main/java/ghidra/framework/cmd/CompoundBackgroundCommand.java +++ b/Ghidra/Framework/Project/src/main/java/ghidra/framework/cmd/CompoundBackgroundCommand.java @@ -1,6 +1,5 @@ /* ### * IP: GHIDRA - * REVIEWED: YES * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,18 +15,19 @@ */ package ghidra.framework.cmd; +import java.util.ArrayList; + import ghidra.framework.model.DomainObject; import ghidra.util.task.TaskMonitor; -import java.util.ArrayList; - /** * Compound command to handle multiple background commands. + * + * @param {@link DomainObject} implementation interface */ -public class CompoundBackgroundCommand extends BackgroundCommand { +public class CompoundBackgroundCommand extends BackgroundCommand { - private ArrayList bkgroundCmdList; - private ArrayList cmdList; + private ArrayList> cmdList; /** * Constructor @@ -38,30 +38,25 @@ public class CompoundBackgroundCommand extends BackgroundCommand { */ public CompoundBackgroundCommand(String name, boolean modal, boolean canCancel) { super(name, false, canCancel, modal); - bkgroundCmdList = new ArrayList(); - cmdList = new ArrayList(); + cmdList = new ArrayList<>(); } - /* (non-Javadoc) - * @see ghidra.framework.cmd.BackgroundCommand#applyTo(ghidra.framework.model.DomainObject, ghidra.util.task.TaskMonitor) - */ @Override - public boolean applyTo(DomainObject obj, TaskMonitor monitor) { - for (int i = 0; i < bkgroundCmdList.size(); i++) { - BackgroundCommand cmd = bkgroundCmdList.get(i); - if (!cmd.applyTo(obj, monitor)) { - setStatusMsg(cmd.getStatusMsg()); - return false; - } - } - for (int i = 0; i < cmdList.size(); i++) { + public boolean applyTo(T obj, TaskMonitor monitor) { + // Run commands in the order they were added + for (Command cmd : cmdList) { if (monitor.isCancelled()) { setStatusMsg("Cancelled"); return false; } - Command cmd = cmdList.get(i); - - if (!cmd.applyTo(obj)) { + boolean success; + if (cmd instanceof BackgroundCommand bcmd) { + success = bcmd.applyTo(obj, monitor); + } + else { + success = cmd.applyTo(obj); + } + if (!success) { setStatusMsg(cmd.getStatusMsg()); return false; } @@ -69,32 +64,27 @@ public class CompoundBackgroundCommand extends BackgroundCommand { return true; } - /** - * Add a background command to this compound background command. - */ - public void add(BackgroundCommand cmd) { - bkgroundCmdList.add(cmd); - } - /** * Add a command to this compound background command. + * @param cmd command to be added */ - public void add(Command cmd) { + public void add(Command cmd) { cmdList.add(cmd); } /** * Get the number of background commands in this compound background * command. + * @return the number of commands */ public int size() { - return bkgroundCmdList.size(); + return cmdList.size(); } /** * @return true if no sub-commands have been added */ public boolean isEmpty() { - return bkgroundCmdList.isEmpty(); + return cmdList.isEmpty(); } } diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/framework/cmd/CompoundCmd.java b/Ghidra/Framework/Project/src/main/java/ghidra/framework/cmd/CompoundCmd.java index ba5e0fc4a7..75eab940d9 100644 --- a/Ghidra/Framework/Project/src/main/java/ghidra/framework/cmd/CompoundCmd.java +++ b/Ghidra/Framework/Project/src/main/java/ghidra/framework/cmd/CompoundCmd.java @@ -1,6 +1,5 @@ /* ### * IP: GHIDRA - * REVIEWED: YES * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,30 +25,26 @@ import java.util.ArrayList; * Multiple commands may be added to this one so that multiple changes can be * applied to the domain object as unit. * - * + * @param {@link DomainObject} implementation interface */ -public class CompoundCmd implements Command { - private ArrayList cmds; +public class CompoundCmd implements Command { + private ArrayList> cmds; private String statusMsg; private String name; - + /** * Constructor for CompoundCmd. * * @param name the name of the command */ public CompoundCmd(String name) { - cmds = new ArrayList(); + cmds = new ArrayList<>(); this.name = name; } - - /* - * @see ghidra.framework.cmd.Command#applyTo(ghidra.framework.model.DomainObject) - */ - public boolean applyTo(DomainObject obj) { - for(int i = 0;i cmd : cmds) { if (!cmd.applyTo(obj)) { statusMsg = cmd.getStatusMsg(); return false; @@ -58,26 +53,22 @@ public class CompoundCmd implements Command { return true; } - /* - * @see ghidra.framework.cmd.Command#getStatusMsg() - */ + @Override public String getStatusMsg() { return statusMsg; } - - /* - * @see ghidra.framework.cmd.Command#getName() - */ + + @Override public String getName() { return name; } - + /** * Add the given command to this command. * * @param cmd command to add to this command */ - public void add(Command cmd) { + public void add(Command cmd) { cmds.add(cmd); } @@ -89,6 +80,5 @@ public class CompoundCmd implements Command { public int size() { return cmds.size(); } - } diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/framework/cmd/MergeableBackgroundCommand.java b/Ghidra/Framework/Project/src/main/java/ghidra/framework/cmd/MergeableBackgroundCommand.java index 48f0924989..c8dfeb8090 100644 --- a/Ghidra/Framework/Project/src/main/java/ghidra/framework/cmd/MergeableBackgroundCommand.java +++ b/Ghidra/Framework/Project/src/main/java/ghidra/framework/cmd/MergeableBackgroundCommand.java @@ -1,6 +1,5 @@ /* ### * IP: GHIDRA - * REVIEWED: YES * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,12 +15,21 @@ */ package ghidra.framework.cmd; -public abstract class MergeableBackgroundCommand extends BackgroundCommand { +import ghidra.framework.model.DomainObject; + +public abstract class MergeableBackgroundCommand + extends BackgroundCommand { + public MergeableBackgroundCommand(String name, boolean hasProgress, boolean canCancel, boolean isModal) { super(name, hasProgress, canCancel, isModal); } - /** Merges the properties of the two commands */ - public abstract MergeableBackgroundCommand mergeCommands(MergeableBackgroundCommand command); + /** + * Merges the properties of the two commands + * @param command command to be merged with this one + * @return resulting merged command + */ + public abstract MergeableBackgroundCommand mergeCommands( + MergeableBackgroundCommand command); } diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/framework/data/DomainObjectAdapterDB.java b/Ghidra/Framework/Project/src/main/java/ghidra/framework/data/DomainObjectAdapterDB.java index 677396f1fe..ec193d83e0 100644 --- a/Ghidra/Framework/Project/src/main/java/ghidra/framework/data/DomainObjectAdapterDB.java +++ b/Ghidra/Framework/Project/src/main/java/ghidra/framework/data/DomainObjectAdapterDB.java @@ -65,7 +65,7 @@ import ghidra.util.task.TaskMonitor; * */ public abstract class DomainObjectAdapterDB extends DomainObjectAdapter - implements UndoableDomainObject, ErrorHandler, DBConstants { + implements ErrorHandler, DBConstants { protected static final int NUM_UNDOS = 50; diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/FileActionManager.java b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/FileActionManager.java index 04dea7803d..85563bf3ab 100644 --- a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/FileActionManager.java +++ b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/FileActionManager.java @@ -352,31 +352,31 @@ class FileActionManager { * all domain objects. */ private DomainObject[] lockDomainObjects(List files) { - DomainObject[] objs = new DomainObject[files.size()]; + DomainObject[] domainObjects = new DomainObject[files.size()]; int lastIndex = 0; boolean locked = true; while (lastIndex < files.size()) { try { - objs[lastIndex] = files.get(lastIndex).getDomainObject(this, false, false, null); + domainObjects[lastIndex] = + files.get(lastIndex).getDomainObject(this, false, false, null); } catch (Throwable t) { Msg.error(this, "Failed to aqcuire domain object instance", t); locked = false; break; } - if (!objs[lastIndex].lock(null)) { + if (!domainObjects[lastIndex].lock(null)) { String title = "Exit Ghidra"; StringBuffer buf = new StringBuffer(); - UndoableDomainObject udo = (UndoableDomainObject) objs[lastIndex]; + DomainObject d = domainObjects[lastIndex]; buf.append("The File " + files.get(lastIndex).getPathname() + " is currently being modified by the\n"); buf.append("the following actions:\n \n"); - TransactionInfo t = udo.getCurrentTransactionInfo(); + TransactionInfo t = d.getCurrentTransactionInfo(); List list = t.getOpenSubTransactions(); - Iterator it = list.iterator(); - while (it.hasNext()) { + for (String element : list) { buf.append("\n "); - buf.append(it.next()); + buf.append(element); } buf.append("\n \n"); buf.append( @@ -391,22 +391,22 @@ class FileActionManager { if (result == OptionDialog.CANCEL_OPTION) { locked = false; - objs[lastIndex].release(this); + domainObjects[lastIndex].release(this); break; } - udo.forceLock(true, null); + d.forceLock(true, null); } ++lastIndex; } if (!locked) { //skip the last one that could not be locked... for (int i = 0; i < lastIndex; i++) { - objs[i].unlock(); - objs[i].release(this); + domainObjects[i].unlock(); + domainObjects[i].release(this); } return null; } - return objs; + return domainObjects; } /** diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/framework/model/DomainObject.java b/Ghidra/Framework/Project/src/main/java/ghidra/framework/model/DomainObject.java index 491b1c8116..72c2e8ed2d 100644 --- a/Ghidra/Framework/Project/src/main/java/ghidra/framework/model/DomainObject.java +++ b/Ghidra/Framework/Project/src/main/java/ghidra/framework/model/DomainObject.java @@ -20,11 +20,16 @@ import java.io.IOException; import java.util.List; import java.util.Map; +import db.TerminatedTransactionException; +import db.Transaction; import ghidra.framework.data.DomainObjectFileListener; import ghidra.framework.options.Options; +import ghidra.framework.store.LockException; import ghidra.util.ReadOnlyException; import ghidra.util.exception.CancelledException; import ghidra.util.task.TaskMonitor; +import utility.function.ExceptionalCallback; +import utility.function.ExceptionalSupplier; /** * DomainObject is the interface that must be supported by @@ -32,6 +37,15 @@ import ghidra.util.task.TaskMonitor; * association with a DomainFile. A DomainObject that * has never been saved will have a null DomainFile. *

+ * Supports transactions and the ability to undo/redo changes made within a stack of + * recent transactions. Each transactions may contain many sub-transactions which + * reflect concurrent changes to the domain object. If any sub-transaction fails to commit, + * all concurrent sub-transaction changes will be rolled-back. + *

+ * NOTE: A transaction must be started in order + * to make any change to this domain object - failure to do so will result in a + * IOException. + *

* Note: Previously (before 11.1), domain object change event types were defined in this file as * integer constants. Event ids have since been converted to enum types. The defines in this file * have been converted to point to the new enum values to make it easier to convert to this new way @@ -376,4 +390,226 @@ public interface DomainObject { * @return a long value that is incremented for every change to the program. */ public long getModificationNumber(); + + /** + * Open new transaction. This should generally be done with a try-with-resources block: + *

+	 * try (Transaction tx = dobj.openTransaction(description)) {
+	 * 	// ... Do something
+	 * }
+	 * 
+ * + * @param description a short description of the changes to be made. + * @return transaction object + * @throws IllegalStateException if this {@link DomainObject} has already been closed. + */ + public Transaction openTransaction(String description) throws IllegalStateException; + + /** + * Performs the given callback inside of a transaction. Use this method in place of the more + * verbose try/catch/finally semantics. + *

+ *

+	 * program.withTransaction("My Description", () -> {
+	 * 	// ... Do something
+	 * });
+	 * 
+ * + *

+ * Note: the transaction created by this method will always be committed when the call is + * finished. If you need the ability to abort transactions, then you need to use the other + * methods on this interface. + * + * @param description brief description of transaction + * @param callback the callback that will be called inside of a transaction + * @throws E any exception that may be thrown in the given callback + */ + public default void withTransaction(String description, + ExceptionalCallback callback) throws E { + int id = startTransaction(description); + try { + callback.call(); + } + finally { + endTransaction(id, true); + } + } + + /** + * Calls the given supplier inside of a transaction. Use this method in place of the more + * verbose try/catch/finally semantics. + *

+ *

+	 * program.withTransaction("My Description", () -> {
+	 * 	// ... Do something
+	 * 	return result;
+	 * });
+	 * 
+ *

+ * If you do not need to supply a result, then use + * {@link #withTransaction(String, ExceptionalCallback)} instead. + * + * @param the exception that may be thrown from this method + * @param the type of result returned by the supplier + * @param description brief description of transaction + * @param supplier the supplier that will be called inside of a transaction + * @return the result returned by the supplier + * @throws E any exception that may be thrown in the given callback + */ + public default T withTransaction(String description, + ExceptionalSupplier supplier) throws E { + T t = null; + boolean success = false; + int id = startTransaction(description); + try { + t = supplier.get(); + success = true; + } + finally { + endTransaction(id, success); + } + return t; + } + + /** + * Start a new transaction in order to make changes to this domain object. + * All changes must be made in the context of a transaction. + * If a transaction is already in progress, a sub-transaction + * of the current transaction will be returned. + * @param description brief description of transaction + * @return transaction ID + * @throws DomainObjectLockedException the domain object is currently locked + * @throws TerminatedTransactionException an existing transaction which has not yet ended was terminated early. + * Sub-transactions are not permitted until the terminated transaction ends. + */ + public int startTransaction(String description); + + /** + * Start a new transaction in order to make changes to this domain object. + * All changes must be made in the context of a transaction. + * If a transaction is already in progress, a sub-transaction + * of the current transaction will be returned. + * @param description brief description of transaction + * @param listener listener to be notified if the transaction is aborted. + * @return transaction ID + * @throws DomainObjectLockedException the domain object is currently locked + * @throws TerminatedTransactionException an existing transaction which has not yet ended was terminated early. + * Sub-transactions are not permitted until the terminated transaction ends. + */ + public int startTransaction(String description, AbortedTransactionListener listener); + + /** + * Terminate the specified transaction for this domain object. + * @param transactionID transaction ID obtained from startTransaction method + * @param commit if true the changes made in this transaction will be marked for commit, + * if false this and any concurrent transaction will be rolled-back. + */ + public void endTransaction(int transactionID, boolean commit); + + /** + * Returns the current transaction info + * @return the current transaction info + */ + public TransactionInfo getCurrentTransactionInfo(); + + /** + * Returns true if the last transaction was terminated from the action that started it. + * @return true if the last transaction was terminated from the action that started it. + */ + public boolean hasTerminatedTransaction(); + + /** + * Return array of all domain objects synchronized with a + * shared transaction manager. + * @return returns array of synchronized domain objects or + * null if this domain object is not synchronized with others. + */ + public DomainObject[] getSynchronizedDomainObjects(); + + /** + * Synchronize the specified domain object with this domain object + * using a shared transaction manager. If either or both is already shared, + * a transition to a single shared transaction manager will be + * performed. + * @param domainObj the domain object + * @throws LockException if lock or open transaction is active on either + * this or the specified domain object + */ + public void addSynchronizedDomainObject(DomainObject domainObj) throws LockException; + + /** + * Remove this domain object from a shared transaction manager. If + * this object has not been synchronized with others via a shared + * transaction manager, this method will have no affect. + * @throws LockException if lock or open transaction is active + */ + public void releaseSynchronizedDomainObject() throws LockException; + + /** + * Returns true if there is a previous state to "undo" to. + */ + boolean canUndo(); + + /** + * Returns true if there is a later state to "redo" to. + */ + boolean canRedo(); + + /** + * Clear all undoable/redoable transactions + */ + public void clearUndo(); + + /** + * Returns to the previous state. Normally, this will cause the current state + * to appear on the "redo" stack. This method will do nothing if there are + * no previous states to "undo". + * @throws IOException if an IO error occurs + */ + void undo() throws IOException; + + /** + * Returns to a latter state that exists because of an undo. Normally, this + * will cause the current state to appear on the "undo" stack. This method + * will do nothing if there are no latter states to "redo". + * @throws IOException if an IO error occurs + */ + void redo() throws IOException; + + /** + * Returns a description of the change that would be "undone". + * @return a description of the change that would be "undone". + */ + public String getUndoName(); + + /** + * Returns a description of the change that would be "redone". + * @return a description of the change that would be "redone". + */ + public String getRedoName(); + + /** + * Returns a list of the names of all current undo transactions + * @return a list of the names of all current undo transactions + */ + public List getAllUndoNames(); + + /** + * Returns a list of the names of all current redo transactions + * @return a list of the names of all current redo transactions + */ + public List getAllRedoNames(); + + /** + * Adds the given transaction listener to this domain object + * @param listener the new transaction listener to add + */ + public void addTransactionListener(TransactionListener listener); + + /** + * Removes the given transaction listener from this domain object. + * @param listener the transaction listener to remove + */ + public void removeTransactionListener(TransactionListener listener); + } diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/framework/model/Undoable.java b/Ghidra/Framework/Project/src/main/java/ghidra/framework/model/Undoable.java deleted file mode 100644 index 433ba9e568..0000000000 --- a/Ghidra/Framework/Project/src/main/java/ghidra/framework/model/Undoable.java +++ /dev/null @@ -1,96 +0,0 @@ -/* ### - * IP: GHIDRA - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ghidra.framework.model; - -import java.io.IOException; -import java.util.List; - -/** - * Objects that implement Undoable have the ability to "remember" some number - * of stable states that are created as operations are performed upon them. The - * object then provides methods for "undoing" to a previous state or "redoing" to - * a later state. - */ -public interface Undoable { - - /** - * Returns true if there is a previous state to "undo" to. - */ - boolean canUndo(); - - /** - * Returns true if there is a later state to "redo" to. - */ - boolean canRedo(); - - /** - * Clear all undoable/redoable transactions - */ - public void clearUndo(); - - /** - * Returns to the previous state. Normally, this will cause the current state - * to appear on the "redo" stack. This method will do nothing if there are - * no previous states to "undo". - * @throws IOException if an IO error occurs - */ - void undo() throws IOException; - - /** - * Returns to a latter state that exists because of an undo. Normally, this - * will cause the current state to appear on the "undo" stack. This method - * will do nothing if there are no latter states to "redo". - * @throws IOException if an IO error occurs - */ - void redo() throws IOException; - - /** - * Returns a description of the change that would be "undone". - * @return a description of the change that would be "undone". - */ - public String getUndoName(); - - /** - * Returns a description of the change that would be "redone". - * @return a description of the change that would be "redone". - */ - public String getRedoName(); - - /** - * Returns a list of the names of all current undo transactions - * @return a list of the names of all current undo transactions - */ - public List getAllUndoNames(); - - /** - * Returns a list of the names of all current redo transactions - * @return a list of the names of all current redo transactions - */ - public List getAllRedoNames(); - - /** - * Adds the given transaction listener to this domain object - * @param listener the new transaction listener to add - */ - public void addTransactionListener(TransactionListener listener); - - /** - * Removes the given transaction listener from this domain object. - * @param listener the transaction listener to remove - */ - public void removeTransactionListener(TransactionListener listener); - -} diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/framework/model/UndoableDomainObject.java b/Ghidra/Framework/Project/src/main/java/ghidra/framework/model/UndoableDomainObject.java deleted file mode 100644 index 9a63b6f98f..0000000000 --- a/Ghidra/Framework/Project/src/main/java/ghidra/framework/model/UndoableDomainObject.java +++ /dev/null @@ -1,193 +0,0 @@ -/* ### - * IP: GHIDRA - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package ghidra.framework.model; - -import db.TerminatedTransactionException; -import db.Transaction; -import ghidra.framework.store.LockException; -import utility.function.ExceptionalCallback; -import utility.function.ExceptionalSupplier; - -/** - * UndoableDomainObject extends a domain object to provide transaction - * support and the ability to undo and redo changes made within a stack of - * recent transactions. Each transactions may contain many sub-transactions which - * reflect concurrent changes to the domain object. If any sub-transaction fails to commit, - * all concurrent sub-transaction changes will be rolled-back. - *

- * NOTE: A transaction must be started in order - * to make any change to this domain object - failure to do so will result in a - * IOException. - * @see #startTransaction(String) - * @see #endTransaction(int, boolean) - */ -public interface UndoableDomainObject extends DomainObject, Undoable { - - /** - * Open new transaction. This should generally be done with a try-with-resources block: - *

-	 * try (Transaction tx = dobj.openTransaction(description)) {
-	 * 	// ... Do something
-	 * }
-	 * 
- * - * @param description a short description of the changes to be made. - * @return transaction object - * @throws IllegalStateException if this {@link DomainObject} has already been closed. - */ - public Transaction openTransaction(String description) throws IllegalStateException; - - /** - * Performs the given callback inside of a transaction. Use this method in place of the more - * verbose try/catch/finally semantics. - *

- *

-	 * program.withTransaction("My Description", () -> {
-	 * 	// ... Do something
-	 * });
-	 * 
- * - *

- * Note: the transaction created by this method will always be committed when the call is - * finished. If you need the ability to abort transactions, then you need to use the other - * methods on this interface. - * - * @param description brief description of transaction - * @param callback the callback that will be called inside of a transaction - * @throws E any exception that may be thrown in the given callback - */ - public default void withTransaction(String description, - ExceptionalCallback callback) throws E { - int id = startTransaction(description); - try { - callback.call(); - } - finally { - endTransaction(id, true); - } - } - - /** - * Calls the given supplier inside of a transaction. Use this method in place of the more - * verbose try/catch/finally semantics. - *

- *

-	 * program.withTransaction("My Description", () -> {
-	 * 	// ... Do something
-	 * 	return result;
-	 * });
-	 * 
- *

- * If you do not need to supply a result, then use - * {@link #withTransaction(String, ExceptionalCallback)} instead. - * - * @param the exception that may be thrown from this method - * @param the type of result returned by the supplier - * @param description brief description of transaction - * @param supplier the supplier that will be called inside of a transaction - * @return the result returned by the supplier - * @throws E any exception that may be thrown in the given callback - */ - public default T withTransaction(String description, - ExceptionalSupplier supplier) throws E { - T t = null; - boolean success = false; - int id = startTransaction(description); - try { - t = supplier.get(); - success = true; - } - finally { - endTransaction(id, success); - } - return t; - } - - /** - * Start a new transaction in order to make changes to this domain object. - * All changes must be made in the context of a transaction. - * If a transaction is already in progress, a sub-transaction - * of the current transaction will be returned. - * @param description brief description of transaction - * @return transaction ID - * @throws DomainObjectLockedException the domain object is currently locked - * @throws TerminatedTransactionException an existing transaction which has not yet ended was terminated early. - * Sub-transactions are not permitted until the terminated transaction ends. - */ - public int startTransaction(String description); - - /** - * Start a new transaction in order to make changes to this domain object. - * All changes must be made in the context of a transaction. - * If a transaction is already in progress, a sub-transaction - * of the current transaction will be returned. - * @param description brief description of transaction - * @param listener listener to be notified if the transaction is aborted. - * @return transaction ID - * @throws DomainObjectLockedException the domain object is currently locked - * @throws TerminatedTransactionException an existing transaction which has not yet ended was terminated early. - * Sub-transactions are not permitted until the terminated transaction ends. - */ - public int startTransaction(String description, AbortedTransactionListener listener); - - /** - * Terminate the specified transaction for this domain object. - * @param transactionID transaction ID obtained from startTransaction method - * @param commit if true the changes made in this transaction will be marked for commit, - * if false this and any concurrent transaction will be rolled-back. - */ - public void endTransaction(int transactionID, boolean commit); - - /** - * Returns the current transaction info - * @return the current transaction info - */ - public TransactionInfo getCurrentTransactionInfo(); - - /** - * Returns true if the last transaction was terminated from the action that started it. - * @return true if the last transaction was terminated from the action that started it. - */ - public boolean hasTerminatedTransaction(); - - /** - * Return array of all domain objects synchronized with a - * shared transaction manager. - * @return returns array of synchronized domain objects or - * null if this domain object is not synchronized with others. - */ - public DomainObject[] getSynchronizedDomainObjects(); - - /** - * Synchronize the specified domain object with this domain object - * using a shared transaction manager. If either or both is already shared, - * a transition to a single shared transaction manager will be - * performed. - * @param domainObj the domain object - * @throws LockException if lock or open transaction is active on either - * this or the specified domain object - */ - public void addSynchronizedDomainObject(DomainObject domainObj) throws LockException; - - /** - * Remove this domain object from a shared transaction manager. If - * this object has not been synchronized with others via a shared - * transaction manager, this method will have no affect. - * @throws LockException if lock or open transaction is active - */ - public void releaseSynchronizedDomainObject() throws LockException; - -} diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/framework/plugintool/PluginTool.java b/Ghidra/Framework/Project/src/main/java/ghidra/framework/plugintool/PluginTool.java index 9db28059a3..47c2362f5b 100644 --- a/Ghidra/Framework/Project/src/main/java/ghidra/framework/plugintool/PluginTool.java +++ b/Ghidra/Framework/Project/src/main/java/ghidra/framework/plugintool/PluginTool.java @@ -25,6 +25,7 @@ import java.net.URL; import java.util.*; import java.util.List; import java.util.concurrent.atomic.AtomicReference; +import java.util.function.Function; import javax.swing.*; @@ -501,8 +502,7 @@ public abstract class PluginTool extends AbstractDockingTool { pluginMgr.close(); if (project != null) { if (project.getToolManager() != null) { - project.getToolManager() - .disconnectTool(this); + project.getToolManager().disconnectTool(this); } } @@ -692,6 +692,39 @@ public abstract class PluginTool extends AbstractDockingTool { eventMgr.processToolEvent(toolEvent); } + /** + * Execute the given command in the foreground. Required domain object transaction will be + * started with delayed end to ensure that any follow-on analysis starts prior to transaction + * end. + * + * @param {@link DomainObject} implementation interface + * @param commandName command name to be associated with transaction + * @param domainObject domain object to be modified + * @param f command function callback which should return true on success or false on failure. + * @return result from command function callback + */ + public boolean execute(String commandName, T domainObject, + Function f) { + return taskMgr.execute(commandName, domainObject, f); + } + + /** + * Execute the given command in the foreground. Required domain object transaction will be + * started with delayed end to ensure that any follow-on analysis starts prior to transaction + * end. + * + * @param {@link DomainObject} implementation interface + * @param commandName command name to be associated with transaction + * @param domainObject domain object to be modified + * @param r command function runnable + */ + public void execute(String commandName, T domainObject, Runnable r) { + execute(commandName, domainObject, d -> { + r.run(); + return true; + }); + } + /** * Call the applyTo() method on the given command to make some change to * the domain object; the command is done in the AWT thread, therefore, @@ -701,9 +734,9 @@ public abstract class PluginTool extends AbstractDockingTool { * @param command command to apply * @param obj domain object that the command will be applied to * @return status of the command's applyTo() method - * @see #executeBackgroundCommand(BackgroundCommand, UndoableDomainObject) + * @see #executeBackgroundCommand(BackgroundCommand, DomainObject) */ - public boolean execute(Command command, DomainObject obj) { + public boolean execute(Command command, T obj) { return taskMgr.execute(command, obj); } @@ -721,8 +754,7 @@ public abstract class PluginTool extends AbstractDockingTool { */ public boolean threadIsBackgroundTaskThread() { ThreadGroup taskGroup = taskMgr.getTaskThreadGroup(); - ThreadGroup group = Thread.currentThread() - .getThreadGroup(); + ThreadGroup group = Thread.currentThread().getThreadGroup(); while (group != null && group != taskGroup) { group = group.getParent(); } @@ -738,7 +770,7 @@ public abstract class PluginTool extends AbstractDockingTool { * AWT Thread) * @param obj domain object that the command will be applied to */ - public void executeBackgroundCommand(BackgroundCommand cmd, UndoableDomainObject obj) { + public void executeBackgroundCommand(BackgroundCommand cmd, T obj) { taskMgr.executeCommand(cmd, obj); } @@ -748,7 +780,7 @@ public abstract class PluginTool extends AbstractDockingTool { * @param cmd background command to submit * @param obj the domain object to be modified by the command. */ - public void scheduleFollowOnCommand(BackgroundCommand cmd, UndoableDomainObject obj) { + public void scheduleFollowOnCommand(BackgroundCommand cmd, T obj) { taskMgr.scheduleFollowOnCommand(cmd, obj); } @@ -1332,8 +1364,7 @@ public abstract class PluginTool extends AbstractDockingTool { * @param height height in pixels */ public void setSize(int width, int height) { - winMgr.getMainWindow() - .setSize(new Dimension(width, height)); + winMgr.getMainWindow().setSize(new Dimension(width, height)); } /** @@ -1341,8 +1372,7 @@ public abstract class PluginTool extends AbstractDockingTool { * @return dimension of this tool's frame */ public Dimension getSize() { - return winMgr.getMainWindow() - .getSize(); + return winMgr.getMainWindow().getSize(); } /** @@ -1351,8 +1381,7 @@ public abstract class PluginTool extends AbstractDockingTool { * @param y screen y coordinate */ public void setLocation(int x, int y) { - winMgr.getMainWindow() - .setLocation(x, y); + winMgr.getMainWindow().setLocation(x, y); } /** @@ -1360,8 +1389,7 @@ public abstract class PluginTool extends AbstractDockingTool { * @return location of this tool's frame */ public Point getLocation() { - return winMgr.getMainWindow() - .getLocation(); + return winMgr.getMainWindow().getLocation(); } private void updateTitle() { diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/framework/plugintool/StandAlonePluginTool.java b/Ghidra/Framework/Project/src/main/java/ghidra/framework/plugintool/StandAlonePluginTool.java index ebd64541f6..1935a2046b 100644 --- a/Ghidra/Framework/Project/src/main/java/ghidra/framework/plugintool/StandAlonePluginTool.java +++ b/Ghidra/Framework/Project/src/main/java/ghidra/framework/plugintool/StandAlonePluginTool.java @@ -27,7 +27,6 @@ import ghidra.util.HelpLocation; public class StandAlonePluginTool extends PluginTool { - private PluginsConfiguration pluginClassManager; private DockingAction configureToolAction; private final GenericStandAloneApplication app; private final String name; diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/framework/plugintool/mgr/BackgroundCommandTask.java b/Ghidra/Framework/Project/src/main/java/ghidra/framework/plugintool/mgr/BackgroundCommandTask.java index 62b5acb15f..3d6b371913 100644 --- a/Ghidra/Framework/Project/src/main/java/ghidra/framework/plugintool/mgr/BackgroundCommandTask.java +++ b/Ghidra/Framework/Project/src/main/java/ghidra/framework/plugintool/mgr/BackgroundCommandTask.java @@ -31,11 +31,12 @@ import ghidra.util.task.TaskMonitor; /** * A task that executes a command in separate thread, not in the Swing Thread */ -class BackgroundCommandTask extends Task implements AbortedTransactionListener { +class BackgroundCommandTask extends Task + implements AbortedTransactionListener { - private BackgroundCommand cmd; + private BackgroundCommand cmd; private ToolTaskManager taskMgr; - private UndoableDomainObject obj; + private T obj; private boolean doneQueueProcessing; @@ -46,8 +47,7 @@ class BackgroundCommandTask extends Task implements AbortedTransactionListener { * @param obj the domain object to be modified by this task. * @param cmd the background command to invoke. */ - public BackgroundCommandTask(ToolTaskManager taskMgr, UndoableDomainObject obj, - BackgroundCommand cmd) { + public BackgroundCommandTask(ToolTaskManager taskMgr, T obj, BackgroundCommand cmd) { super(cmd.getName(), cmd.canCancel(), cmd.hasProgress(), cmd.isModal()); this.cmd = cmd; this.taskMgr = taskMgr; @@ -58,7 +58,7 @@ class BackgroundCommandTask extends Task implements AbortedTransactionListener { * Returns the Domain Object associated with this Task * @return the object */ - public UndoableDomainObject getDomainObject() { + public T getDomainObject() { return obj; } @@ -67,7 +67,7 @@ class BackgroundCommandTask extends Task implements AbortedTransactionListener { * * @return background command */ - public BackgroundCommand getCommand() { + public BackgroundCommand getCommand() { return cmd; } diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/framework/plugintool/mgr/ToolTaskManager.java b/Ghidra/Framework/Project/src/main/java/ghidra/framework/plugintool/mgr/ToolTaskManager.java index f5ba6c13e4..6ed721b5a0 100644 --- a/Ghidra/Framework/Project/src/main/java/ghidra/framework/plugintool/mgr/ToolTaskManager.java +++ b/Ghidra/Framework/Project/src/main/java/ghidra/framework/plugintool/mgr/ToolTaskManager.java @@ -20,12 +20,14 @@ import java.rmi.ConnectException; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.*; +import java.util.function.Function; import javax.swing.JComponent; import javax.swing.SwingUtilities; import ghidra.framework.cmd.*; -import ghidra.framework.model.*; +import ghidra.framework.model.DomainObject; +import ghidra.framework.model.DomainObjectException; import ghidra.framework.plugintool.PluginTool; import ghidra.util.*; import ghidra.util.datastruct.PriorityQueue; @@ -44,16 +46,15 @@ public class ToolTaskManager implements Runnable { private volatile PluginTool tool; private volatile boolean isExecuting; - private LinkedList tasks = new LinkedList<>(); - private Map> queuedCommandsMap = + private LinkedList> tasks = new LinkedList<>(); + private Map>> queuedCommandsMap = new HashMap<>(); - private Map openForgroundTransactionIDs = new HashMap<>(); private long startQueueTime = 0; private long startTaskTime = 0; private Thread taskThread; private ThreadGroup taskThreadGroup; private ToolTaskMonitor toolTaskMonitor; - private BackgroundCommandTask currentTask; + private BackgroundCommandTask currentTask; private TaskDialog modalTaskDialog; /** @@ -98,7 +99,25 @@ public class ToolTaskManager implements Runnable { } /** - * Execute the given command in the foreground + * Execute the given command in the foreground. Required domain object transaction will be + * started with delayed end to ensure that any follow-on analysis starts prior to transaction + * end. + * + * @param {@link DomainObject} implementation interface + * @param commandName command name to be associated with transaction + * @param domainObject domain object to be modified + * @param f command function callback which should return true on success or false on failure. + * @return result from command function callback + */ + public boolean execute(String commandName, T domainObject, + Function f) { + return execute(new SimpleCommand(commandName, f), domainObject); + } + + /** + * Execute the given command in the foreground. Required domain object transaction will be + * started with delayed end to ensure that any follow-on analysis starts prior to transaction + * end. * * @param cmd command to execute * @param obj domain object to which the command will be applied @@ -106,7 +125,7 @@ public class ToolTaskManager implements Runnable { * * @see Command#applyTo(DomainObject) */ - public boolean execute(Command cmd, DomainObject obj) { + public boolean execute(Command cmd, T obj) { if (tool == null) { return false; // disposed } @@ -115,13 +134,7 @@ public class ToolTaskManager implements Runnable { boolean success = false; isExecuting = true; try { - if (obj instanceof UndoableDomainObject) { - UndoableDomainObject undoObj = (UndoableDomainObject) obj; - success = applyCommand(cmd, undoObj); - } - else { - success = cmd.applyTo(obj); - } + success = applyCommand(cmd, obj); } finally { isExecuting = false; @@ -139,20 +152,20 @@ public class ToolTaskManager implements Runnable { return success; } - private boolean applyCommand(Command cmd, UndoableDomainObject domainObject) { + private boolean applyCommand(Command cmd, T domainObject) { boolean success = false; boolean error = false; String cmdName = cmd.getName(); - int id = domainObject.startTransaction(cmdName); + int txId = domainObject.startTransaction(cmdName); try { try { success = cmd.applyTo(domainObject); - // TODO Ok, this seems bad--why track the success of the given command, but - // not any of the queued commands? (Are they considered unrelated follow-up - // commands?) - executeQueueCommands(domainObject, cmdName); + // Schedule empty background task to trigger flushEvents and processing of + // resulting queued commands. This is standard behavior when any + // BackgroundCommand completes its execution (see taskCompleted method). + executeCommand(new EmptyBackgroundCommand(cmdName), domainObject); } catch (Throwable t) { error = true; @@ -174,7 +187,7 @@ public class ToolTaskManager implements Runnable { } } finally { - domainObject.endTransaction(id, !error); + domainObject.endTransaction(txId, !error); } return success; @@ -186,12 +199,13 @@ public class ToolTaskManager implements Runnable { * @param cmd background command * @param obj domain object that supports undo/redo */ - public synchronized void executeCommand(BackgroundCommand cmd, UndoableDomainObject obj) { + public synchronized void executeCommand(BackgroundCommand cmd, + T obj) { if (tool == null) { return; } - BackgroundCommandTask task = new BackgroundCommandTask(this, obj, cmd); + BackgroundCommandTask task = new BackgroundCommandTask<>(this, obj, cmd); tasks.addLast(task); if (taskThread != null && taskThread.isAlive()) { @@ -202,9 +216,9 @@ public class ToolTaskManager implements Runnable { taskThread.setPriority(Thread.MIN_PRIORITY + 1); taskThread.start(); try { - // We will get notified by the task, after it has started the transaction - - // TODO: why do we need to wait until the transaction is started?!? + // Wait for background command task to start its transaction and notify us. + // This is done to ensure any preceeding foreground Command transaction + // becomes entangled with the task execution. wait(1000); } catch (InterruptedException e) { @@ -219,11 +233,12 @@ public class ToolTaskManager implements Runnable { * @param cmd background command to be scheduled * @param obj domain object that supports undo/redo */ - public synchronized void scheduleFollowOnCommand(BackgroundCommand cmd, - UndoableDomainObject obj) { + public synchronized void scheduleFollowOnCommand( + BackgroundCommand cmd, T obj) { + if (isProcessingDomainObject(obj)) { - PriorityQueue queue = queuedCommandsMap.get(obj); + PriorityQueue> queue = queuedCommandsMap.get(obj); if (queue == null) { queue = new PriorityQueue<>(); queuedCommandsMap.put(obj, queue); @@ -239,7 +254,7 @@ public class ToolTaskManager implements Runnable { } } - private boolean isProcessingDomainObject(UndoableDomainObject obj) { + private boolean isProcessingDomainObject(DomainObject obj) { if (taskThread == null) { return false; } @@ -252,9 +267,10 @@ public class ToolTaskManager implements Runnable { return currentTask != null && !currentTask.isDoneQueueProcessing(); } - private boolean mergeMergeableBackgroundCommands(BackgroundCommand newCommand, - PriorityQueue queue) { - BackgroundCommand lastCommand = queue.getLast(); + private boolean mergeMergeableBackgroundCommands( + BackgroundCommand newCommand, PriorityQueue> queue) { + @SuppressWarnings("unchecked") + BackgroundCommand lastCommand = (BackgroundCommand) queue.getLast(); if (!(lastCommand instanceof MergeableBackgroundCommand) || !(newCommand instanceof MergeableBackgroundCommand)) { return false; @@ -262,10 +278,10 @@ public class ToolTaskManager implements Runnable { // merge the two into the original command, as it is still in the queue in the correct // place - MergeableBackgroundCommand mergeableBackgroundCommand = - (MergeableBackgroundCommand) lastCommand; - MergeableBackgroundCommand newMergeableBackgroundCommand = - (MergeableBackgroundCommand) newCommand; + MergeableBackgroundCommand mergeableBackgroundCommand = + (MergeableBackgroundCommand) lastCommand; + MergeableBackgroundCommand newMergeableBackgroundCommand = + (MergeableBackgroundCommand) newCommand; mergeableBackgroundCommand.mergeCommands(newMergeableBackgroundCommand); return true; } @@ -315,9 +331,10 @@ public class ToolTaskManager implements Runnable { Msg.debug(this, time() + "Background processing started..."); startQueueTime = System.currentTimeMillis(); - for (BackgroundCommandTask task = getNextTask(); task != null; task = getNextTask()) { + for (BackgroundCommandTask task = getNextTask(); task != null; task = + getNextTask()) { - Msg.debug(this, time() + "Exec Task " + task.getTaskTitle()); + Msg.debug(this, time() + "Task Start: " + task.getTaskTitle()); startTaskTime = System.currentTimeMillis(); synchronized (this) { @@ -345,7 +362,7 @@ public class ToolTaskManager implements Runnable { } } - private synchronized BackgroundCommandTask getNextTask() { + private synchronized BackgroundCommandTask getNextTask() { if (tasks.isEmpty()) { taskThread = null; return null; @@ -353,12 +370,13 @@ public class ToolTaskManager implements Runnable { return tasks.removeFirst(); } - private synchronized BackgroundCommand getNextCommand(UndoableDomainObject obj) { - PriorityQueue queue = queuedCommandsMap.get(obj); + private synchronized BackgroundCommand getNextCommand(T obj) { + PriorityQueue> queue = queuedCommandsMap.get(obj); if (queue == null) { return null; } - BackgroundCommand cmd = queue.removeFirst(); + @SuppressWarnings("unchecked") + BackgroundCommand cmd = (BackgroundCommand) queue.removeFirst(); if (queue.isEmpty()) { queuedCommandsMap.remove(obj); } @@ -373,15 +391,14 @@ public class ToolTaskManager implements Runnable { * @param task background command task that has completed * @param monitor task monitor */ - public void taskCompleted(UndoableDomainObject obj, BackgroundCommandTask task, + public void taskCompleted(T obj, BackgroundCommandTask task, TaskMonitor monitor) { - double taskTime = (System.currentTimeMillis() - startTaskTime) / 1000.00; - Msg.debug(this, time() + task.getTaskTitle() + " task finish (" + taskTime + " secs)"); obj.flushEvents(); + try { while (!monitor.isCancelled()) { - BackgroundCommand cmd; + BackgroundCommand cmd; synchronized (this) { cmd = getNextCommand(obj); if (cmd == null) { @@ -390,13 +407,14 @@ public class ToolTaskManager implements Runnable { break; } } - Msg.debug(this, time() + "Queue - " + cmd.getName()); + Msg.debug(this, time() + "Start: " + cmd.getName()); toolTaskMonitor.updateTaskCmd(cmd); long localStart = System.currentTimeMillis(); cmd.applyTo(obj, monitor); cmd.taskCompleted(); double totalTime = (System.currentTimeMillis() - localStart) / 1000.00; - Msg.debug(this, time() + "(" + totalTime + " secs)"); + Msg.debug(this, + time() + "Completed: " + cmd.getName() + " (" + totalTime + " secs)"); obj.flushEvents(); } } @@ -408,12 +426,6 @@ public class ToolTaskManager implements Runnable { tool.setStatusInfo(task.getCommand().getName() + " cancelled"); } } - synchronized (this) { - Integer openForgroundTransactionID = openForgroundTransactionIDs.remove(obj); - if (openForgroundTransactionID != null) { - obj.endTransaction(openForgroundTransactionID, true); - } - } } finally { if (currentTask.isModal()) { @@ -427,20 +439,21 @@ public class ToolTaskManager implements Runnable { } task.getCommand().taskCompleted(); double totalTime = (System.currentTimeMillis() - startTaskTime) / 1000.00; - Msg.debug(this, time() + task.getTaskTitle() + " task complete (" + totalTime + " secs)"); + Msg.debug(this, + time() + "Task Completed: " + task.getTaskTitle() + " (" + totalTime + " secs)"); } /** * Clear the queue of scheduled commands. * @param obj domain object */ - public synchronized void clearQueuedCommands(UndoableDomainObject obj) { - PriorityQueue queue = queuedCommandsMap.get(obj); + public synchronized void clearQueuedCommands(DomainObject obj) { + PriorityQueue> queue = queuedCommandsMap.get(obj); if (queue == null) { return; } while (!queue.isEmpty()) { - BackgroundCommand cmd = queue.removeFirst(); + BackgroundCommand cmd = queue.removeFirst(); cmd.dispose(); } queuedCommandsMap.remove(obj); @@ -451,10 +464,10 @@ public class ToolTaskManager implements Runnable { * * @param obj domain object */ - public synchronized void clearTasks(UndoableDomainObject obj) { - Iterator iter = tasks.iterator(); + public synchronized void clearTasks(DomainObject obj) { + Iterator> iter = tasks.iterator(); while (iter.hasNext()) { - BackgroundCommandTask task = iter.next(); + BackgroundCommandTask task = iter.next(); if (task.getDomainObject() == obj) { iter.remove(); } @@ -469,7 +482,7 @@ public class ToolTaskManager implements Runnable { * @param taskCmd background command that failed * @param monitor task monitor for the background task */ - public void taskFailed(UndoableDomainObject obj, BackgroundCommand taskCmd, + public void taskFailed(T obj, BackgroundCommand taskCmd, TaskMonitor monitor) { try { obj.flushEvents(); @@ -499,36 +512,15 @@ public class ToolTaskManager implements Runnable { } } - private void executeQueueCommands(UndoableDomainObject obj, String title) { - obj.flushEvents(); - synchronized (this) { - PriorityQueue queue = queuedCommandsMap.get(obj); - if (queue == null) { - return; // nothing is queued - } - if (!openForgroundTransactionIDs.containsKey(obj)) { - // persist transaction to include follow-on changes - openForgroundTransactionIDs.put(obj, obj.startTransaction(title)); - } - } - // schedule task to process command queue - BackgroundCommand cmd = new EmptyBackgroundCommand(); - executeCommand(cmd, obj); - } - /** * Clear list of tasks and queue of scheduled commands. */ public synchronized void dispose() { clearTasks(); - List list = new ArrayList<>(queuedCommandsMap.keySet()); - for (UndoableDomainObject obj : list) { + List list = new ArrayList<>(queuedCommandsMap.keySet()); + for (DomainObject obj : list) { clearQueuedCommands(obj); - Integer txId = openForgroundTransactionIDs.get(obj); - if (txId != null) { - obj.endTransaction(txId, true); - } } queuedCommandsMap = new HashMap<>(); @@ -567,9 +559,7 @@ public class ToolTaskManager implements Runnable { } private synchronized boolean hasQueuedTasksForDomainObject(DomainObject domainObject) { - Iterator iter = tasks.iterator(); - while (iter.hasNext()) { - BackgroundCommandTask task = iter.next(); + for (BackgroundCommandTask task : tasks) { if (task.getDomainObject() == domainObject) { return true; } @@ -577,21 +567,49 @@ public class ToolTaskManager implements Runnable { return false; } -} + private static class EmptyBackgroundCommand + extends BackgroundCommand { -class EmptyBackgroundCommand extends BackgroundCommand { + public EmptyBackgroundCommand(String name) { + super(name, false, true, false); + } - public EmptyBackgroundCommand() { - super("Empty Background Command", false, true, false); + @Override + public boolean applyTo(T obj, TaskMonitor monitor) { + return true; + } } /** - * @see ghidra.framework.cmd.BackgroundCommand#applyTo(ghidra.framework.model.DomainObject, - * ghidra.util.task.TaskMonitor) + * {@link SimpleCommand} provides a convenience command for wrapping a lambda function + * into a foreground {@link Command} for execution by the task manager. + * + * @param {@link DomainObject} implementation class */ - @Override - public boolean applyTo(DomainObject obj, TaskMonitor monitor) { - return true; + private static class SimpleCommand implements Command { + + private String commandName; + private Function f; + + SimpleCommand(String commandName, Function f) { + this.commandName = commandName; + this.f = f; + } + + @Override + public boolean applyTo(T domainObject) { + return f.apply(domainObject); + } + + @Override + public String getStatusMsg() { + return null; + } + + @Override + public String getName() { + return commandName; + } } } @@ -614,7 +632,7 @@ class ToolTaskMonitor extends TaskMonitorComponent implements TaskListener { }; } - public void updateTaskCmd(BackgroundCommand cmd) { + public void updateTaskCmd(BackgroundCommand cmd) { showProgress(cmd.hasProgress()); setTaskName(cmd.getName()); } diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/framework/task/GTask.java b/Ghidra/Framework/Project/src/main/java/ghidra/framework/task/GTask.java index a3977386a1..1525382767 100644 --- a/Ghidra/Framework/Project/src/main/java/ghidra/framework/task/GTask.java +++ b/Ghidra/Framework/Project/src/main/java/ghidra/framework/task/GTask.java @@ -1,6 +1,5 @@ /* ### * IP: GHIDRA - * REVIEWED: YES * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,7 +15,7 @@ */ package ghidra.framework.task; -import ghidra.framework.model.UndoableDomainObject; +import ghidra.framework.model.DomainObject; import ghidra.util.exception.CancelledException; import ghidra.util.task.TaskMonitor; @@ -39,7 +38,6 @@ public interface GTask { * @param monitor the taskMonitor to be used to cancel and report progress. * @throws CancelledException if the user cancelled the task. */ - public void run(UndoableDomainObject domainObject, TaskMonitor monitor) - throws CancelledException; + public void run(DomainObject domainObject, TaskMonitor monitor) throws CancelledException; } diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/framework/task/GTaskManager.java b/Ghidra/Framework/Project/src/main/java/ghidra/framework/task/GTaskManager.java index a3de7e9036..76cb23ad0b 100644 --- a/Ghidra/Framework/Project/src/main/java/ghidra/framework/task/GTaskManager.java +++ b/Ghidra/Framework/Project/src/main/java/ghidra/framework/task/GTaskManager.java @@ -21,13 +21,14 @@ import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.ReentrantLock; import generic.concurrent.GThreadPool; -import ghidra.framework.model.*; +import ghidra.framework.model.DomainObject; +import ghidra.framework.model.DomainObjectClosedListener; import ghidra.util.Msg; import ghidra.util.exception.CancelledException; /** * Class for managing a queue of tasks to be executed, one at a time, in priority order. All the - * tasks pertain to an UndoableDomainObject and transactions are created on the UndoableDomainObject + * tasks pertain to an DomainObject and transactions are created on the DomainObject * so that tasks can operate on them. *

* Tasks are organized into groups such that all tasks in a group will be completed before the @@ -36,7 +37,7 @@ import ghidra.util.exception.CancelledException; * in the order that they are scheduled. *

* All tasks within the same group are executed within the same transaction on the - * UndoableDomainObject. When all the tasks within a group are completed, the transaction is closed + * DomainObject. When all the tasks within a group are completed, the transaction is closed * unless there is another group scheduled and that group does not specify that it should run in its * own transaction. *

@@ -59,7 +60,7 @@ public class GTaskManager { private static final int MAX_RESULTS = 100; - private UndoableDomainObject domainObject; + private DomainObject domainObject; // value will be set to null on close private SortedSet priorityQ = new TreeSet(); private Deque taskGroupList = new LinkedList(); private GThreadPool threadPool; @@ -82,14 +83,14 @@ public class GTaskManager { private Queue results = new ArrayDeque(); /** - * Creates a new GTaskManager for an UndoableDomainObject - * @param undoableDomainObject the domainObject that tasks scheduled in this GTaskManager will + * Creates a new GTaskManager for an DomainObject + * @param domainObject the domainObject that tasks scheduled in this GTaskManager will * operate upon. * @param threadPool the GThreadPool that will provide the threads that will be used to run * tasks in this GTaskManager. */ - public GTaskManager(UndoableDomainObject undoableDomainObject, GThreadPool threadPool) { - this.domainObject = undoableDomainObject; + public GTaskManager(DomainObject domainObject, GThreadPool threadPool) { + this.domainObject = domainObject; this.threadPool = threadPool; domainObject.addCloseListener(new DomainObjectClosedListener() { @@ -97,7 +98,7 @@ public class GTaskManager { public void domainObjectClosed(DomainObject dobj) { // assert dobj == domainObj GTaskManagerFactory.domainObjectClosed(domainObject); - domainObject = null; + GTaskManager.this.domainObject = null; } }); } @@ -111,6 +112,7 @@ public class GTaskManager { * if one exists. If false, any open transaction * will be closed and a new transaction will be opened before * this task is run. + * @return scheduled task */ public GScheduledTask scheduleTask(GTask task, int priority, boolean useCurrentGroup) { GScheduledTask newTask; @@ -154,7 +156,7 @@ public class GTaskManager { * * @param task the task to be run. * @param priority the priority of the task. Lower numbers are run before higher numbers. - * @param groupName. The name of the group that the task will be added to. + * @param groupName The name of the group that the task will be added to. */ public void scheduleTask(GTask task, int priority, String groupName) { lock.lock(); @@ -616,14 +618,16 @@ public class GTaskManager { } private void openTransaction(String description) { - if (currentGroupTransactionID == null) { + DomainObject d = domainObject; + if (d != null && currentGroupTransactionID == null) { currentGroupTransactionID = domainObject.startTransaction(description); } } private void closeTransaction() { - if (currentGroupTransactionID != null) { - domainObject.endTransaction(currentGroupTransactionID, true); + DomainObject d = domainObject; + if (d != null && currentGroupTransactionID != null) { + d.endTransaction(currentGroupTransactionID, true); currentGroupTransactionID = null; } } @@ -763,12 +767,13 @@ public class GTaskManager { scheduledTask.setThread(Thread.currentThread()); notifyTaskStarted(scheduledTask); - if (scheduledTask.getGroup().wasCancelled()) { + DomainObject d = domainObject; + if (d == null || scheduledTask.getGroup().wasCancelled()) { taskCompleted(scheduledTask, new CancelledException()); return; } - scheduledTask.getTask().run(domainObject, scheduledTask.getTaskMonitor()); + scheduledTask.getTask().run(d, scheduledTask.getTaskMonitor()); taskCompleted(scheduledTask, null); } catch (Exception e) { diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/framework/task/GTaskManagerFactory.java b/Ghidra/Framework/Project/src/main/java/ghidra/framework/task/GTaskManagerFactory.java index 24108c7023..a9243b42fd 100644 --- a/Ghidra/Framework/Project/src/main/java/ghidra/framework/task/GTaskManagerFactory.java +++ b/Ghidra/Framework/Project/src/main/java/ghidra/framework/task/GTaskManagerFactory.java @@ -1,6 +1,5 @@ /* ### * IP: GHIDRA - * REVIEWED: YES * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,20 +15,20 @@ */ package ghidra.framework.task; -import generic.concurrent.GThreadPool; -import ghidra.framework.model.UndoableDomainObject; -import ghidra.util.exception.AssertException; - import java.util.Map; import java.util.WeakHashMap; +import generic.concurrent.GThreadPool; +import ghidra.framework.model.DomainObject; +import ghidra.util.exception.AssertException; + /** - * Factory class managing a single GTaskManager for an UndoableDomainObject. + * Factory class managing a single GTaskManager for an DomainObject. * */ public class GTaskManagerFactory { - private static Map map = - new WeakHashMap(); + private static Map map = + new WeakHashMap(); /** * Returns the one GTaskManager for the domainObject. A new GTaskManager will be created if @@ -38,7 +37,7 @@ public class GTaskManagerFactory { * @param domainObject the domainObject for which to get a GTaskManager. * @return the GTaskManager for the given domainObject. */ - public static GTaskManager getTaskManager(UndoableDomainObject domainObject) { + public static GTaskManager getTaskManager(DomainObject domainObject) { if (domainObject.isClosed()) { throw new AssertException("Attempted to get a TaskManger for a closed domain object"); } @@ -51,7 +50,7 @@ public class GTaskManagerFactory { return gTaskManager; } - static void domainObjectClosed(UndoableDomainObject domainObject) { + static void domainObjectClosed(DomainObject domainObject) { map.remove(domainObject); } } diff --git a/Ghidra/Framework/Project/src/test.slow/java/ghidra/framework/task/gui/GTaskGUITest.java b/Ghidra/Framework/Project/src/test.slow/java/ghidra/framework/task/gui/GTaskGUITest.java index f151c12fa7..b6a7c91ed1 100644 --- a/Ghidra/Framework/Project/src/test.slow/java/ghidra/framework/task/gui/GTaskGUITest.java +++ b/Ghidra/Framework/Project/src/test.slow/java/ghidra/framework/task/gui/GTaskGUITest.java @@ -28,7 +28,7 @@ import org.junit.*; import docking.test.AbstractDockingTest; import generic.concurrent.GThreadPool; -import ghidra.framework.model.UndoableDomainObject; +import ghidra.framework.model.DomainObject; import ghidra.framework.task.*; import ghidra.framework.task.gui.taskview.*; import ghidra.util.exception.CancelledException; @@ -412,8 +412,9 @@ public class GTaskGUITest extends AbstractDockingTest { private void assertWaitingCount(int count) { waitForSwing(); - waitForCondition(() -> count == getWaitingCount(), "Timed-out waiting for the 'wait count' to be " + count + ", but was " + - getWaitingCount()); + waitForCondition(() -> count == getWaitingCount(), + "Timed-out waiting for the 'wait count' to be " + count + ", but was " + + getWaitingCount()); } private int getWaitingCount() { @@ -647,11 +648,12 @@ public class GTaskGUITest extends AbstractDockingTest { } void waitForWorkFinished(int n) { - waitForCondition(() -> workCount.get() == n, "Work iteration " + n + " never completed"); + waitForCondition(() -> workCount.get() == n, + "Work iteration " + n + " never completed"); } @Override - public void run(UndoableDomainObject obj, TaskMonitor monitor) throws CancelledException { + public void run(DomainObject obj, TaskMonitor monitor) throws CancelledException { debug(getName() + ": Run called"); monitor.initialize(loopCount); taskStartLatch.countDown(); diff --git a/Ghidra/Framework/Project/src/test/java/ghidra/framework/task/GTaskTest.java b/Ghidra/Framework/Project/src/test/java/ghidra/framework/task/GTaskTest.java index 26415348f8..8759ae9dce 100644 --- a/Ghidra/Framework/Project/src/test/java/ghidra/framework/task/GTaskTest.java +++ b/Ghidra/Framework/Project/src/test/java/ghidra/framework/task/GTaskTest.java @@ -28,7 +28,7 @@ import org.junit.*; import generic.concurrent.GThreadPool; import generic.test.AbstractGenericTest; -import ghidra.framework.model.UndoableDomainObject; +import ghidra.framework.model.DomainObject; import ghidra.util.exception.CancelledException; import ghidra.util.task.TaskMonitor; @@ -480,7 +480,7 @@ public class GTaskTest extends AbstractGenericTest { } @Override - public void run(UndoableDomainObject obj, TaskMonitor monitor) throws CancelledException { + public void run(DomainObject obj, TaskMonitor monitor) throws CancelledException { try { if (!latch.await(2, TimeUnit.SECONDS)) { Assert.fail("Latch await expired!"); @@ -500,7 +500,7 @@ public class GTaskTest extends AbstractGenericTest { } @Override - public void run(UndoableDomainObject obj, TaskMonitor monitor) throws CancelledException { + public void run(DomainObject obj, TaskMonitor monitor) throws CancelledException { GTaskManager taskManager = GTaskManagerFactory.getTaskManager(obj); taskManager.waitForHigherPriorityTasks(); super.run(obj, monitor); diff --git a/Ghidra/Framework/Project/src/test/java/ghidra/framework/task/SimpleTask.java b/Ghidra/Framework/Project/src/test/java/ghidra/framework/task/SimpleTask.java index 2d4b1f7f76..a4d22c4a50 100644 --- a/Ghidra/Framework/Project/src/test/java/ghidra/framework/task/SimpleTask.java +++ b/Ghidra/Framework/Project/src/test/java/ghidra/framework/task/SimpleTask.java @@ -15,7 +15,7 @@ */ package ghidra.framework.task; -import ghidra.framework.model.UndoableDomainObject; +import ghidra.framework.model.DomainObject; import ghidra.util.exception.CancelledException; import ghidra.util.task.TaskMonitor; @@ -35,7 +35,7 @@ public class SimpleTask implements GTask { } @Override - public void run(UndoableDomainObject obj, TaskMonitor monitor) throws CancelledException { + public void run(DomainObject obj, TaskMonitor monitor) throws CancelledException { monitor.checkCancelled(); didRun = true; } diff --git a/Ghidra/Framework/Project/src/test/java/ghidra/framework/task/TaskSimulator.java b/Ghidra/Framework/Project/src/test/java/ghidra/framework/task/TaskSimulator.java index cd97797a62..b9595cb2b3 100644 --- a/Ghidra/Framework/Project/src/test/java/ghidra/framework/task/TaskSimulator.java +++ b/Ghidra/Framework/Project/src/test/java/ghidra/framework/task/TaskSimulator.java @@ -28,7 +28,7 @@ import docking.widgets.checkbox.GCheckBox; import generic.concurrent.GThreadPool; import ghidra.GhidraApplicationLayout; import ghidra.framework.Application; -import ghidra.framework.model.UndoableDomainObject; +import ghidra.framework.model.DomainObject; import ghidra.util.exception.CancelledException; import ghidra.util.task.TaskMonitor; @@ -193,8 +193,7 @@ public class TaskSimulator { } @Override - public void run(UndoableDomainObject domainObject, TaskMonitor monitor) - throws CancelledException { + public void run(DomainObject domainObject, TaskMonitor monitor) throws CancelledException { monitor.initialize(count); diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/DataTypeManagerDomainObject.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/DataTypeManagerDomainObject.java index 48ca226da1..069f01c453 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/DataTypeManagerDomainObject.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/DataTypeManagerDomainObject.java @@ -1,6 +1,5 @@ /* ### * IP: GHIDRA - * REVIEWED: YES * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,7 +16,7 @@ package ghidra.program.model.data; import ghidra.app.merge.DataTypeManagerOwner; -import ghidra.framework.model.UndoableDomainObject; +import ghidra.framework.model.DomainObject; -public interface DataTypeManagerDomainObject extends UndoableDomainObject, DataTypeManagerOwner { +public interface DataTypeManagerDomainObject extends DomainObject, DataTypeManagerOwner { } diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/listing/ParameterImpl.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/listing/ParameterImpl.java index 718c4dc290..911d1b6c09 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/listing/ParameterImpl.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/listing/ParameterImpl.java @@ -79,7 +79,7 @@ public class ParameterImpl extends VariableImpl implements Parameter { * @param name variable name or null for default name * @param dataType a fixed-length datatype. (NOTE: Should be cloned to program datatype manager * prior to determining storage elements since their length may change) - * @param stackOffset + * @param stackOffset parameter stack offset * @param program target program * @throws InvalidInputException if dataType restrictions are violated, an invalid storage * address is specified, or unable to resolve storage element for specified datatype @@ -97,7 +97,7 @@ public class ParameterImpl extends VariableImpl implements Parameter { * @param name variable name or null for default name * @param dataType a fixed-length datatype. (NOTE: Should be cloned to program datatype manager * prior to determining storage elements since their length may change) - * @param stackOffset + * @param stackOffset parameter stack offset * @param program target program * @param sourceType name source type * @throws InvalidInputException if dataType restrictions are violated, an invalid storage @@ -116,7 +116,7 @@ public class ParameterImpl extends VariableImpl implements Parameter { * @param name variable name or null for default name * @param dataType a fixed-length datatype. (NOTE: Should be cloned to program datatype manager * prior to determining storage elements since their length may change) - * @param register + * @param register parameter register storage * @param program target program * @throws InvalidInputException if dataType restrictions are violated, an invalid storage * address is specified, or unable to resolve storage element for specified datatype @@ -132,7 +132,7 @@ public class ParameterImpl extends VariableImpl implements Parameter { * @param name variable name or null for default name * @param dataType a fixed-length datatype. (NOTE: Should be cloned to program datatype manager * prior to determining storage elements since their length may change) - * @param register + * @param register parameter register storage * @param program target program * @param sourceType name source type * @throws InvalidInputException if dataType restrictions are violated, an invalid storage diff --git a/Ghidra/Test/IntegrationTest/src/screen/java/help/screenshot/AutoAnalysisPluginScreenShots.java b/Ghidra/Test/IntegrationTest/src/screen/java/help/screenshot/AutoAnalysisPluginScreenShots.java index ec9bef3903..45c2312d54 100644 --- a/Ghidra/Test/IntegrationTest/src/screen/java/help/screenshot/AutoAnalysisPluginScreenShots.java +++ b/Ghidra/Test/IntegrationTest/src/screen/java/help/screenshot/AutoAnalysisPluginScreenShots.java @@ -107,7 +107,7 @@ public class AutoAnalysisPluginScreenShots extends GhidraScreenShotGenerator { // Inner Classes //================================================================================================== - class TestBackgroundCommand extends BackgroundCommand { + class TestBackgroundCommand extends BackgroundCommand { private CountDownLatch start; private CountDownLatch end; diff --git a/Ghidra/Test/IntegrationTest/src/screen/java/help/screenshot/ToolScreenShots.java b/Ghidra/Test/IntegrationTest/src/screen/java/help/screenshot/ToolScreenShots.java index a6fc5d602b..5953b79323 100644 --- a/Ghidra/Test/IntegrationTest/src/screen/java/help/screenshot/ToolScreenShots.java +++ b/Ghidra/Test/IntegrationTest/src/screen/java/help/screenshot/ToolScreenShots.java @@ -309,7 +309,7 @@ public class ToolScreenShots extends GhidraScreenShotGenerator { return helpTopicDirs; } - private class DummyBackgroundCommand extends BackgroundCommand { + private static class DummyBackgroundCommand extends BackgroundCommand { public DummyBackgroundCommand() { super("Dummy", true, true, false);