GP-4390 Collapse DomainObject Undoable interfaces and refactor Command processing.

This commit is contained in:
ghidra1 2024-03-08 12:49:50 -05:00
parent 136b933af2
commit 445494ba25
214 changed files with 2862 additions and 3813 deletions

View file

@ -322,8 +322,7 @@ public class TraceRmiHandler implements TraceRmiConnection {
} }
} }
protected DomainFolder getOrCreateNewTracesFolder() protected DomainFolder getOrCreateNewTracesFolder() throws InvalidNameException, IOException {
throws InvalidNameException, IOException {
return getOrCreateFolder(plugin.getTool().getProject().getProjectData().getRootFolder(), return getOrCreateFolder(plugin.getTool().getProject().getProjectData().getRootFolder(),
"New Traces"); "New Traces");
} }
@ -494,10 +493,8 @@ public class TraceRmiHandler implements TraceRmiConnection {
return rep == null ? null : rep.build(); return rep == null ? null : rep.build();
} }
catch (Throwable e) { catch (Throwable e) {
return rep return rep.setError(ReplyError.newBuilder()
.setError(ReplyError.newBuilder() .setMessage(e.getMessage() + "\n" + ExceptionUtils.getStackTrace(e)))
.setMessage(
e.getMessage() + "\n" + ExceptionUtils.getStackTrace(e)))
.build(); .build();
} }
} }
@ -509,8 +506,8 @@ public class TraceRmiHandler implements TraceRmiConnection {
req.getRequestActivate().getOid().getId(), req.getRequestActivate().getOid().getId(),
req.getRequestActivate().getObject().getId(), req.getRequestActivate().getObject().getId(),
req.getRequestActivate().getObject().getPath().getPath()); req.getRequestActivate().getObject().getPath().getPath());
case REQUEST_END_TX -> "endTx(%d)".formatted( case REQUEST_END_TX -> "endTx(%d)"
req.getRequestEndTx().getTxid().getId()); .formatted(req.getRequestEndTx().getTxid().getId());
case REQUEST_START_TX -> "startTx(%d,%s)".formatted( case REQUEST_START_TX -> "startTx(%d,%s)".formatted(
req.getRequestStartTx().getTxid().getId(), req.getRequestStartTx().getTxid().getId(),
req.getRequestStartTx().getDescription()); req.getRequestStartTx().getDescription());
@ -530,49 +527,40 @@ public class TraceRmiHandler implements TraceRmiConnection {
} }
final Dispatcher dispatchNegotiate = (req, rep) -> switch (req.getMsgCase()) { final Dispatcher dispatchNegotiate = (req, rep) -> switch (req.getMsgCase()) {
case REQUEST_NEGOTIATE -> rep case REQUEST_NEGOTIATE -> rep.setReplyNegotiate(handleNegotiate(req.getRequestNegotiate()));
.setReplyNegotiate(handleNegotiate(req.getRequestNegotiate()));
default -> throw new InvalidRequestError(req); default -> throw new InvalidRequestError(req);
}; };
final Dispatcher dispatchNominal = (req, rep) -> switch (req.getMsgCase()) { final Dispatcher dispatchNominal = (req, rep) -> switch (req.getMsgCase()) {
case REQUEST_ACTIVATE -> rep case REQUEST_ACTIVATE -> rep.setReplyActivate(handleActivate(req.getRequestActivate()));
.setReplyActivate(handleActivate(req.getRequestActivate()));
case REQUEST_CLOSE_TRACE -> rep case REQUEST_CLOSE_TRACE -> rep
.setReplyCloseTrace(handleCloseTrace(req.getRequestCloseTrace())); .setReplyCloseTrace(handleCloseTrace(req.getRequestCloseTrace()));
case REQUEST_CREATE_OBJECT -> rep case REQUEST_CREATE_OBJECT -> rep
.setReplyCreateObject(handleCreateObject(req.getRequestCreateObject())); .setReplyCreateObject(handleCreateObject(req.getRequestCreateObject()));
case REQUEST_CREATE_OVERLAY -> rep case REQUEST_CREATE_OVERLAY -> rep
.setReplyCreateOverlay( .setReplyCreateOverlay(handleCreateOverlay(req.getRequestCreateOverlay()));
handleCreateOverlay(req.getRequestCreateOverlay()));
case REQUEST_CREATE_ROOT_OBJECT -> rep case REQUEST_CREATE_ROOT_OBJECT -> rep
.setReplyCreateObject( .setReplyCreateObject(handleCreateRootObject(req.getRequestCreateRootObject()));
handleCreateRootObject(req.getRequestCreateRootObject()));
case REQUEST_CREATE_TRACE -> rep case REQUEST_CREATE_TRACE -> rep
.setReplyCreateTrace(handleCreateTrace(req.getRequestCreateTrace())); .setReplyCreateTrace(handleCreateTrace(req.getRequestCreateTrace()));
case REQUEST_DELETE_BYTES -> rep case REQUEST_DELETE_BYTES -> rep
.setReplyDeleteBytes(handleDeleteBytes(req.getRequestDeleteBytes())); .setReplyDeleteBytes(handleDeleteBytes(req.getRequestDeleteBytes()));
case REQUEST_DELETE_REGISTER_VALUE -> rep case REQUEST_DELETE_REGISTER_VALUE -> rep.setReplyDeleteRegisterValue(
.setReplyDeleteRegisterValue(
handleDeleteRegisterValue(req.getRequestDeleteRegisterValue())); handleDeleteRegisterValue(req.getRequestDeleteRegisterValue()));
case REQUEST_DISASSEMBLE -> rep case REQUEST_DISASSEMBLE -> rep
.setReplyDisassemble(handleDisassemble(req.getRequestDisassemble())); .setReplyDisassemble(handleDisassemble(req.getRequestDisassemble()));
case REQUEST_END_TX -> rep case REQUEST_END_TX -> rep.setReplyEndTx(handleEndTx(req.getRequestEndTx()));
.setReplyEndTx(handleEndTx(req.getRequestEndTx()));
case REQUEST_GET_OBJECT -> rep case REQUEST_GET_OBJECT -> rep
.setReplyGetObject(handleGetObject(req.getRequestGetObject())); .setReplyGetObject(handleGetObject(req.getRequestGetObject()));
case REQUEST_GET_VALUES -> rep case REQUEST_GET_VALUES -> rep
.setReplyGetValues(handleGetValues(req.getRequestGetValues())); .setReplyGetValues(handleGetValues(req.getRequestGetValues()));
case REQUEST_GET_VALUES_INTERSECTING -> rep case REQUEST_GET_VALUES_INTERSECTING -> rep.setReplyGetValues(
.setReplyGetValues(
handleGetValuesIntersecting(req.getRequestGetValuesIntersecting())); handleGetValuesIntersecting(req.getRequestGetValuesIntersecting()));
case REQUEST_INSERT_OBJECT -> rep case REQUEST_INSERT_OBJECT -> rep
.setReplyInsertObject(handleInsertObject(req.getRequestInsertObject())); .setReplyInsertObject(handleInsertObject(req.getRequestInsertObject()));
case REQUEST_PUT_BYTES -> rep case REQUEST_PUT_BYTES -> rep.setReplyPutBytes(handlePutBytes(req.getRequestPutBytes()));
.setReplyPutBytes(handlePutBytes(req.getRequestPutBytes()));
case REQUEST_PUT_REGISTER_VALUE -> rep case REQUEST_PUT_REGISTER_VALUE -> rep
.setReplyPutRegisterValue( .setReplyPutRegisterValue(handlePutRegisterValue(req.getRequestPutRegisterValue()));
handlePutRegisterValue(req.getRequestPutRegisterValue()));
case REQUEST_REMOVE_OBJECT -> rep case REQUEST_REMOVE_OBJECT -> rep
.setReplyRemoveObject(handleRemoveObject(req.getRequestRemoveObject())); .setReplyRemoveObject(handleRemoveObject(req.getRequestRemoveObject()));
case REQUEST_RETAIN_VALUES -> rep case REQUEST_RETAIN_VALUES -> rep
@ -580,14 +568,10 @@ public class TraceRmiHandler implements TraceRmiConnection {
case REQUEST_SAVE_TRACE -> rep case REQUEST_SAVE_TRACE -> rep
.setReplySaveTrace(handleSaveTrace(req.getRequestSaveTrace())); .setReplySaveTrace(handleSaveTrace(req.getRequestSaveTrace()));
case REQUEST_SET_MEMORY_STATE -> rep case REQUEST_SET_MEMORY_STATE -> rep
.setReplySetMemoryState( .setReplySetMemoryState(handleSetMemoryState(req.getRequestSetMemoryState()));
handleSetMemoryState(req.getRequestSetMemoryState())); case REQUEST_SET_VALUE -> rep.setReplySetValue(handleSetValue(req.getRequestSetValue()));
case REQUEST_SET_VALUE -> rep case REQUEST_SNAPSHOT -> rep.setReplySnapshot(handleSnapshot(req.getRequestSnapshot()));
.setReplySetValue(handleSetValue(req.getRequestSetValue())); case REQUEST_START_TX -> rep.setReplyStartTx(handleStartTx(req.getRequestStartTx()));
case REQUEST_SNAPSHOT -> rep
.setReplySnapshot(handleSnapshot(req.getRequestSnapshot()));
case REQUEST_START_TX -> rep
.setReplyStartTx(handleStartTx(req.getRequestStartTx()));
case XREPLY_INVOKE_METHOD -> handleXInvokeMethod(req.getXreplyInvokeMethod()); case XREPLY_INVOKE_METHOD -> handleXInvokeMethod(req.getXreplyInvokeMethod());
default -> throw new InvalidRequestError(req); default -> throw new InvalidRequestError(req);
}; };
@ -666,15 +650,11 @@ public class TraceRmiHandler implements TraceRmiConnection {
} }
protected static ObjSpec makeObjSpec(TraceObject object) { protected static ObjSpec makeObjSpec(TraceObject object) {
return ObjSpec.newBuilder() return ObjSpec.newBuilder().setId(object.getKey()).build();
.setId(object.getKey())
.build();
} }
protected static ObjPath makeObjPath(TraceObjectKeyPath path) { protected static ObjPath makeObjPath(TraceObjectKeyPath path) {
return ObjPath.newBuilder() return ObjPath.newBuilder().setPath(path.toString()).build();
.setPath(path.toString())
.build();
} }
protected static ObjDesc makeObjDesc(TraceObject object) { protected static ObjDesc makeObjDesc(TraceObject object) {
@ -767,15 +747,13 @@ public class TraceRmiHandler implements TraceRmiConnection {
if (value instanceof int[] ia) { if (value instanceof int[] ia) {
return Value.newBuilder() return Value.newBuilder()
.setIntArrValue( .setIntArrValue(
IntArr.newBuilder() IntArr.newBuilder().addAllArr(IntStream.of(ia).mapToObj(i -> i).toList()))
.addAllArr(IntStream.of(ia).mapToObj(i -> i).toList()))
.build(); .build();
} }
if (value instanceof long[] la) { if (value instanceof long[] la) {
return Value.newBuilder() return Value.newBuilder()
.setLongArrValue( .setLongArrValue(
LongArr.newBuilder() LongArr.newBuilder().addAllArr(LongStream.of(la).mapToObj(l -> l).toList()))
.addAllArr(LongStream.of(la).mapToObj(l -> l).toList()))
.build(); .build();
} }
if (value instanceof String[] sa) { if (value instanceof String[] sa) {
@ -847,8 +825,7 @@ public class TraceRmiHandler implements TraceRmiConnection {
protected ReplyCreateObject handleCreateObject(RequestCreateObject req) { protected ReplyCreateObject handleCreateObject(RequestCreateObject req) {
OpenTrace open = requireOpenTrace(req.getOid()); OpenTrace open = requireOpenTrace(req.getOid());
TraceObject object = TraceObject object = open.trace.getObjectManager().createObject(toKeyPath(req.getPath()));
open.trace.getObjectManager().createObject(toKeyPath(req.getPath()));
return ReplyCreateObject.newBuilder().setObject(makeObjSpec(object)).build(); return ReplyCreateObject.newBuilder().setObject(makeObjSpec(object)).build();
} }
@ -904,8 +881,7 @@ public class TraceRmiHandler implements TraceRmiConnection {
return ReplyDeleteBytes.getDefaultInstance(); return ReplyDeleteBytes.getDefaultInstance();
} }
protected ReplyDeleteRegisterValue handleDeleteRegisterValue( protected ReplyDeleteRegisterValue handleDeleteRegisterValue(RequestDeleteRegisterValue req) {
RequestDeleteRegisterValue req) {
OpenTrace open = requireOpenTrace(req.getOid()); OpenTrace open = requireOpenTrace(req.getOid());
long snap = req.getSnap().getSnap(); long snap = req.getSnap().getSnap();
AddressSpace space = open.trace.getBaseAddressFactory().getAddressSpace(req.getSpace()); AddressSpace space = open.trace.getBaseAddressFactory().getAddressSpace(req.getSpace());
@ -932,15 +908,13 @@ public class TraceRmiHandler implements TraceRmiConnection {
// Want addresses satisfying {@code known | (readOnly & everKnown)} // Want addresses satisfying {@code known | (readOnly & everKnown)}
TraceMemoryManager memoryManager = open.trace.getMemoryManager(); TraceMemoryManager memoryManager = open.trace.getMemoryManager();
AddressSetView readOnly = AddressSetView readOnly = memoryManager.getRegionsAddressSetWith(snap, r -> !r.isWrite());
memoryManager.getRegionsAddressSetWith(snap, r -> !r.isWrite());
AddressSetView everKnown = memoryManager.getAddressesWithState(Lifespan.since(snap), AddressSetView everKnown = memoryManager.getAddressesWithState(Lifespan.since(snap),
s -> s == TraceMemoryState.KNOWN); s -> s == TraceMemoryState.KNOWN);
AddressSetView roEverKnown = new IntersectionAddressSetView(readOnly, everKnown); AddressSetView roEverKnown = new IntersectionAddressSetView(readOnly, everKnown);
AddressSetView known = AddressSetView known =
memoryManager.getAddressesWithState(snap, s -> s == TraceMemoryState.KNOWN); memoryManager.getAddressesWithState(snap, s -> s == TraceMemoryState.KNOWN);
AddressSetView disassemblable = AddressSetView disassemblable = new AddressSet(new UnionAddressSetView(known, roEverKnown));
new AddressSet(new UnionAddressSetView(known, roEverKnown));
Address start = open.toAddress(req.getStart(), true); Address start = open.toAddress(req.getStart(), true);
TracePlatform host = open.trace.getPlatformManager().getHostPlatform(); TracePlatform host = open.trace.getPlatformManager().getHostPlatform();
@ -950,7 +924,7 @@ public class TraceRmiHandler implements TraceRmiConnection {
host.getLanguage(), host.getLanguage().getLanguageID(), start)); host.getLanguage(), host.getLanguage().getLanguageID(), start));
try (CloseableTaskMonitor monitor = plugin.createMonitor()) { try (CloseableTaskMonitor monitor = plugin.createMonitor()) {
dis.applyToTyped(open.trace.getFixedProgramView(snap), monitor); dis.applyTo(open.trace.getFixedProgramView(snap), monitor);
} }
return ReplyDisassemble.newBuilder() return ReplyDisassemble.newBuilder()
@ -988,21 +962,19 @@ public class TraceRmiHandler implements TraceRmiConnection {
OpenTrace open = requireOpenTrace(req.getOid()); OpenTrace open = requireOpenTrace(req.getOid());
return ReplyGetValues.newBuilder() return ReplyGetValues.newBuilder()
.addAllValues(open.trace.getObjectManager() .addAllValues(open.trace.getObjectManager()
.getValuePaths(toLifespan(req.getSpan()), .getValuePaths(toLifespan(req.getSpan()), toPathPattern(req.getPattern()))
toPathPattern(req.getPattern()))
.map(TraceRmiHandler::makeValDesc) .map(TraceRmiHandler::makeValDesc)
.sorted(Comparator.comparing(ValDesc::getKey)) .sorted(Comparator.comparing(ValDesc::getKey))
.toList()) .toList())
.build(); .build();
} }
protected ReplyGetValues handleGetValuesIntersecting( protected ReplyGetValues handleGetValuesIntersecting(RequestGetValuesIntersecting req)
RequestGetValuesIntersecting req) throws AddressOverflowException { throws AddressOverflowException {
OpenTrace open = requireOpenTrace(req.getOid()); OpenTrace open = requireOpenTrace(req.getOid());
AddressRange range = open.toRange(req.getBox().getRange(), false); AddressRange range = open.toRange(req.getBox().getRange(), false);
String key = req.getKey() == "" ? null : req.getKey(); String key = req.getKey() == "" ? null : req.getKey();
Collection<? extends TraceObjectValue> col = range == null Collection<? extends TraceObjectValue> col = range == null ? List.of()
? List.of()
: open.trace.getObjectManager() : open.trace.getObjectManager()
.getValuesIntersecting(toLifespan(req.getBox().getSpan()), range, key); .getValuesIntersecting(toLifespan(req.getBox().getSpan()), range, key);
return ReplyGetValues.newBuilder() return ReplyGetValues.newBuilder()
@ -1018,9 +990,7 @@ public class TraceRmiHandler implements TraceRmiConnection {
.stream() .stream()
.map(TraceObjectValue::getLifespan) .map(TraceObjectValue::getLifespan)
.reduce(Lifespan.ALL, Lifespan::intersect); .reduce(Lifespan.ALL, Lifespan::intersect);
return ReplyInsertObject.newBuilder() return ReplyInsertObject.newBuilder().setSpan(makeSpan(span)).build();
.setSpan(makeSpan(span))
.build();
} }
protected ReplyNegotiate handleNegotiate(RequestNegotiate req) { protected ReplyNegotiate handleNegotiate(RequestNegotiate req) {
@ -1031,8 +1001,8 @@ public class TraceRmiHandler implements TraceRmiConnection {
} }
for (Method m : req.getMethodsList()) { for (Method m : req.getMethodsList()) {
RemoteMethod rm = new RecordRemoteMethod(this, m.getName(), RemoteMethod rm = new RecordRemoteMethod(this, m.getName(),
ActionName.name(m.getAction()), m.getDisplay(), ActionName.name(m.getAction()), m.getDisplay(), m.getDescription(),
m.getDescription(), m.getParametersList() m.getParametersList()
.stream() .stream()
.collect(Collectors.toMap(MethodParameter::getName, this::makeParameter)), .collect(Collectors.toMap(MethodParameter::getName, this::makeParameter)),
new SchemaName(m.getReturnType().getName())); new SchemaName(m.getReturnType().getName()));
@ -1141,8 +1111,7 @@ public class TraceRmiHandler implements TraceRmiConnection {
return ReplySetMemoryState.getDefaultInstance(); return ReplySetMemoryState.getDefaultInstance();
} }
protected ReplySetValue handleSetValue(RequestSetValue req) protected ReplySetValue handleSetValue(RequestSetValue req) throws AddressOverflowException {
throws AddressOverflowException {
ValSpec value = req.getValue(); ValSpec value = req.getValue();
OpenTrace open = requireOpenTrace(req.getOid()); OpenTrace open = requireOpenTrace(req.getOid());
Object objVal = open.toValue(value.getValue()); Object objVal = open.toValue(value.getValue());
@ -1152,8 +1121,8 @@ public class TraceRmiHandler implements TraceRmiConnection {
return ReplySetValue.newBuilder().setSpan(makeSpan(Lifespan.EMPTY)).build(); return ReplySetValue.newBuilder().setSpan(makeSpan(Lifespan.EMPTY)).build();
} }
TraceObjectValue val = object.setValue(toLifespan(value.getSpan()), value.getKey(), TraceObjectValue val = object.setValue(toLifespan(value.getSpan()), value.getKey(), objVal,
objVal, toResolution(req.getResolution())); toResolution(req.getResolution()));
return ReplySetValue.newBuilder() return ReplySetValue.newBuilder()
.setSpan(makeSpan(val == null ? Lifespan.EMPTY : val.getLifespan())) .setSpan(makeSpan(val == null ? Lifespan.EMPTY : val.getLifespan()))
.build(); .build();

View file

@ -22,7 +22,7 @@ import ghidra.app.services.DebuggerTraceManagerService;
import ghidra.debug.api.platform.DebuggerPlatformMapper; import ghidra.debug.api.platform.DebuggerPlatformMapper;
import ghidra.debug.api.platform.DisassemblyResult; import ghidra.debug.api.platform.DisassemblyResult;
import ghidra.debug.api.tracemgr.DebuggerCoordinates; import ghidra.debug.api.tracemgr.DebuggerCoordinates;
import ghidra.framework.cmd.TypedBackgroundCommand; import ghidra.framework.cmd.BackgroundCommand;
import ghidra.framework.plugintool.PluginTool; import ghidra.framework.plugintool.PluginTool;
import ghidra.program.model.address.Address; import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressSetView; import ghidra.program.model.address.AddressSetView;
@ -33,7 +33,7 @@ import ghidra.trace.model.thread.TraceThread;
import ghidra.util.task.TaskMonitor; import ghidra.util.task.TaskMonitor;
public final class CurrentPlatformTraceDisassembleCommand public final class CurrentPlatformTraceDisassembleCommand
extends TypedBackgroundCommand<TraceProgramView> { extends BackgroundCommand<TraceProgramView> {
public static final String NAME = "Disassemble"; public static final String NAME = "Disassemble";
public record Reqs(DebuggerPlatformMapper mapper, TraceThread thread, TraceObject object, public record Reqs(DebuggerPlatformMapper mapper, TraceThread thread, TraceObject object,
@ -48,8 +48,7 @@ public final class CurrentPlatformTraceDisassembleCommand
return null; return null;
} }
Trace trace = view.getTrace(); Trace trace = view.getTrace();
DebuggerCoordinates current = traceManager == null DebuggerCoordinates current = traceManager == null ? DebuggerCoordinates.NOWHERE
? DebuggerCoordinates.NOWHERE
: traceManager.getCurrentFor(trace); : traceManager.getCurrentFor(trace);
TraceThread thread = current.getThread(); TraceThread thread = current.getThread();
TraceObject object = current.getObject(); TraceObject object = current.getObject();
@ -74,8 +73,8 @@ public final class CurrentPlatformTraceDisassembleCommand
private final Reqs reqs; private final Reqs reqs;
private final Address address; private final Address address;
public CurrentPlatformTraceDisassembleCommand(PluginTool tool, AddressSetView set, public CurrentPlatformTraceDisassembleCommand(PluginTool tool, AddressSetView set, Reqs reqs,
Reqs reqs, Address address) { Address address) {
super(NAME, true, true, false); super(NAME, true, true, false);
this.tool = tool; this.tool = tool;
this.set = set; this.set = set;
@ -84,9 +83,9 @@ public final class CurrentPlatformTraceDisassembleCommand
} }
@Override @Override
public boolean applyToTyped(TraceProgramView view, TaskMonitor monitor) { public boolean applyTo(TraceProgramView view, TaskMonitor monitor) {
DisassemblyResult result = reqs.mapper.disassemble( DisassemblyResult result = reqs.mapper.disassemble(reqs.thread, reqs.object, address, set,
reqs.thread, reqs.object, address, set, view.getSnap(), monitor); view.getSnap(), monitor);
if (!result.isSuccess()) { if (!result.isSuccess()) {
tool.setStatusInfo(result.getErrorMessage(), true); tool.setStatusInfo(result.getErrorMessage(), true);
} }

View file

@ -15,7 +15,7 @@
*/ */
package ghidra.app.plugin.core.debug.disassemble; 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.disassemble.Disassembler;
import ghidra.program.model.address.*; import ghidra.program.model.address.*;
import ghidra.program.model.lang.*; import ghidra.program.model.lang.*;
@ -27,7 +27,7 @@ import ghidra.trace.model.program.TraceProgramView;
import ghidra.util.MathUtilities; import ghidra.util.MathUtilities;
import ghidra.util.task.TaskMonitor; import ghidra.util.task.TaskMonitor;
public class TraceDisassembleCommand extends TypedBackgroundCommand<TraceProgramView> { public class TraceDisassembleCommand extends BackgroundCommand<TraceProgramView> {
protected final TracePlatform platform; protected final TracePlatform platform;
protected final Address start; protected final Address start;
@ -76,7 +76,7 @@ public class TraceDisassembleCommand extends TypedBackgroundCommand<TraceProgram
} }
@Override @Override
public boolean applyToTyped(TraceProgramView view, TaskMonitor monitor) { public boolean applyTo(TraceProgramView view, TaskMonitor monitor) {
Disassembler disassembler = getDisassembler(view, monitor); Disassembler disassembler = getDisassembler(view, monitor);
MemBuffer buffer = getBuffer(view); MemBuffer buffer = getBuffer(view);
if (buffer == null) { if (buffer == null) {

View file

@ -73,8 +73,8 @@ public abstract class AbstractDebuggerPlatformMapper implements DebuggerPlatform
} }
@Override @Override
public DisassemblyResult disassemble(TraceThread thread, TraceObject object, public DisassemblyResult disassemble(TraceThread thread, TraceObject object, Address start,
Address start, AddressSetView restricted, long snap, TaskMonitor monitor) { AddressSetView restricted, long snap, TaskMonitor monitor) {
if (isCancelSilently(start, snap)) { if (isCancelSilently(start, snap)) {
return DisassemblyResult.CANCELLED; return DisassemblyResult.CANCELLED;
} }
@ -86,7 +86,7 @@ public abstract class AbstractDebuggerPlatformMapper implements DebuggerPlatform
for (DisassemblyInject i : injects) { for (DisassemblyInject i : injects) {
i.pre(tool, dis, platform, snap, thread, startSet, restricted); i.pre(tool, dis, platform, snap, thread, startSet, restricted);
} }
boolean result = dis.applyToTyped(trace.getFixedProgramView(snap), monitor); boolean result = dis.applyTo(trace.getFixedProgramView(snap), monitor);
if (!result) { if (!result) {
return DisassemblyResult.failed(dis.getStatusMsg()); return DisassemblyResult.failed(dis.getStatusMsg());
} }

View file

@ -24,8 +24,8 @@ import org.apache.commons.lang3.concurrent.BasicThreadFactory;
import ghidra.app.plugin.core.debug.utils.DefaultTransactionCoalescer; import ghidra.app.plugin.core.debug.utils.DefaultTransactionCoalescer;
import ghidra.app.plugin.core.debug.utils.TransactionCoalescer; import ghidra.app.plugin.core.debug.utils.TransactionCoalescer;
import ghidra.app.plugin.core.debug.utils.TransactionCoalescer.CoalescedTx; import ghidra.app.plugin.core.debug.utils.TransactionCoalescer.CoalescedTx;
import ghidra.framework.model.DomainObject;
import ghidra.framework.model.DomainObjectException; import ghidra.framework.model.DomainObjectException;
import ghidra.framework.model.UndoableDomainObject;
import ghidra.util.Msg; import ghidra.util.Msg;
import ghidra.util.exception.ClosedException; import ghidra.util.exception.ClosedException;
@ -33,16 +33,16 @@ public class PermanentTransactionExecutor {
private final TransactionCoalescer txc; private final TransactionCoalescer txc;
private final ExecutorService[] threads; private final ExecutorService[] threads;
private final UndoableDomainObject obj; private final DomainObject obj;
public PermanentTransactionExecutor(UndoableDomainObject obj, String name, int threadCount, public PermanentTransactionExecutor(DomainObject obj, String name, int threadCount,
int delayMs) { int delayMs) {
this.obj = obj; this.obj = obj;
txc = new DefaultTransactionCoalescer<>(obj, RecorderPermanentTransaction::start, delayMs); txc = new DefaultTransactionCoalescer<>(obj, RecorderPermanentTransaction::start, delayMs);
this.threads = new ExecutorService[threadCount]; this.threads = new ExecutorService[threadCount];
for (int i = 0; i < threadCount; i++) { for (int i = 0; i < threadCount; i++) {
ThreadFactory factory = new BasicThreadFactory.Builder() ThreadFactory factory =
.namingPattern(name + "thread-" + i + "-%d") new BasicThreadFactory.Builder().namingPattern(name + "thread-" + i + "-%d")
.build(); .build();
threads[i] = Executors.newSingleThreadExecutor(factory); threads[i] = Executors.newSingleThreadExecutor(factory);
} }

View file

@ -16,19 +16,19 @@
package ghidra.app.plugin.core.debug.service.model; package ghidra.app.plugin.core.debug.service.model;
import db.Transaction; import db.Transaction;
import ghidra.framework.model.UndoableDomainObject; import ghidra.framework.model.DomainObject;
public class RecorderPermanentTransaction implements AutoCloseable { 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); Transaction tx = obj.openTransaction(description);
return new RecorderPermanentTransaction(obj, tx); return new RecorderPermanentTransaction(obj, tx);
} }
private final UndoableDomainObject obj; private final DomainObject obj;
private final Transaction tx; private final Transaction tx;
public RecorderPermanentTransaction(UndoableDomainObject obj, Transaction tx) { public RecorderPermanentTransaction(DomainObject obj, Transaction tx) {
this.obj = obj; this.obj = obj;
this.tx = tx; this.tx = tx;
} }

View file

@ -20,11 +20,11 @@ import java.util.Collection;
import ghidra.app.services.DebuggerStaticMappingService; import ghidra.app.services.DebuggerStaticMappingService;
import ghidra.debug.api.modules.ModuleMapProposal.ModuleMapEntry; import ghidra.debug.api.modules.ModuleMapProposal.ModuleMapEntry;
import ghidra.framework.cmd.BackgroundCommand; import ghidra.framework.cmd.BackgroundCommand;
import ghidra.framework.model.DomainObject; import ghidra.trace.model.Trace;
import ghidra.util.exception.CancelledException; import ghidra.util.exception.CancelledException;
import ghidra.util.task.TaskMonitor; import ghidra.util.task.TaskMonitor;
public class MapModulesBackgroundCommand extends BackgroundCommand { public class MapModulesBackgroundCommand extends BackgroundCommand<Trace> {
private final DebuggerStaticMappingService service; private final DebuggerStaticMappingService service;
private final Collection<ModuleMapEntry> entries; private final Collection<ModuleMapEntry> entries;
@ -36,7 +36,7 @@ public class MapModulesBackgroundCommand extends BackgroundCommand {
} }
@Override @Override
public boolean applyTo(DomainObject obj, TaskMonitor monitor) { public boolean applyTo(Trace trace, TaskMonitor monitor) {
try { try {
service.addModuleMappings(entries, monitor, true); service.addModuleMappings(entries, monitor, true);
} }

View file

@ -20,11 +20,11 @@ import java.util.Collection;
import ghidra.app.services.DebuggerStaticMappingService; import ghidra.app.services.DebuggerStaticMappingService;
import ghidra.debug.api.modules.RegionMapProposal.RegionMapEntry; import ghidra.debug.api.modules.RegionMapProposal.RegionMapEntry;
import ghidra.framework.cmd.BackgroundCommand; import ghidra.framework.cmd.BackgroundCommand;
import ghidra.framework.model.DomainObject; import ghidra.trace.model.Trace;
import ghidra.util.exception.CancelledException; import ghidra.util.exception.CancelledException;
import ghidra.util.task.TaskMonitor; import ghidra.util.task.TaskMonitor;
public class MapRegionsBackgroundCommand extends BackgroundCommand { public class MapRegionsBackgroundCommand extends BackgroundCommand<Trace> {
private final DebuggerStaticMappingService service; private final DebuggerStaticMappingService service;
private final Collection<RegionMapEntry> entries; private final Collection<RegionMapEntry> entries;
@ -36,7 +36,7 @@ public class MapRegionsBackgroundCommand extends BackgroundCommand {
} }
@Override @Override
public boolean applyTo(DomainObject obj, TaskMonitor monitor) { public boolean applyTo(Trace trace, TaskMonitor monitor) {
try { try {
service.addRegionMappings(entries, monitor, true); service.addRegionMappings(entries, monitor, true);
} }

View file

@ -20,11 +20,11 @@ import java.util.Collection;
import ghidra.app.services.DebuggerStaticMappingService; import ghidra.app.services.DebuggerStaticMappingService;
import ghidra.debug.api.modules.SectionMapProposal.SectionMapEntry; import ghidra.debug.api.modules.SectionMapProposal.SectionMapEntry;
import ghidra.framework.cmd.BackgroundCommand; import ghidra.framework.cmd.BackgroundCommand;
import ghidra.framework.model.DomainObject; import ghidra.trace.model.Trace;
import ghidra.util.exception.CancelledException; import ghidra.util.exception.CancelledException;
import ghidra.util.task.TaskMonitor; import ghidra.util.task.TaskMonitor;
public class MapSectionsBackgroundCommand extends BackgroundCommand { public class MapSectionsBackgroundCommand extends BackgroundCommand<Trace> {
private final DebuggerStaticMappingService service; private final DebuggerStaticMappingService service;
private final Collection<SectionMapEntry> entries; private final Collection<SectionMapEntry> entries;
@ -36,7 +36,7 @@ public class MapSectionsBackgroundCommand extends BackgroundCommand {
} }
@Override @Override
public boolean applyTo(DomainObject obj, TaskMonitor monitor) { public boolean applyTo(Trace trace, TaskMonitor monitor) {
try { try {
service.addSectionMappings(entries, monitor, true); service.addSectionMappings(entries, monitor, true);
} }

View file

@ -16,7 +16,7 @@
package ghidra.app.plugin.core.debug.stack; package ghidra.app.plugin.core.debug.stack;
import ghidra.debug.api.tracemgr.DebuggerCoordinates; import ghidra.debug.api.tracemgr.DebuggerCoordinates;
import ghidra.framework.cmd.TypedBackgroundCommand; import ghidra.framework.cmd.BackgroundCommand;
import ghidra.framework.plugintool.PluginTool; import ghidra.framework.plugintool.PluginTool;
import ghidra.pcode.exec.DebuggerPcodeUtils.WatchValue; import ghidra.pcode.exec.DebuggerPcodeUtils.WatchValue;
import ghidra.trace.model.Trace; 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 * A command to unwind as much of the stack as possible and annotate the resulting frame in the
* dynamic listing * dynamic listing
*/ */
public class UnwindStackCommand extends TypedBackgroundCommand<Trace> { public class UnwindStackCommand extends BackgroundCommand<Trace> {
private final PluginTool tool; private final PluginTool tool;
private final DebuggerCoordinates where; private final DebuggerCoordinates where;
@ -39,7 +39,7 @@ public class UnwindStackCommand extends TypedBackgroundCommand<Trace> {
} }
@Override @Override
public boolean applyToTyped(Trace obj, TaskMonitor monitor) { public boolean applyTo(Trace obj, TaskMonitor monitor) {
try { try {
StackUnwinder unwinder = new StackUnwinder(tool, where.getPlatform()); StackUnwinder unwinder = new StackUnwinder(tool, where.getPlatform());
int prevParamSize = 0; int prevParamSize = 0;

View file

@ -25,7 +25,6 @@ import org.apache.commons.lang3.exception.ExceptionUtils;
import ghidra.async.AsyncUtils; import ghidra.async.AsyncUtils;
import ghidra.framework.cmd.BackgroundCommand; import ghidra.framework.cmd.BackgroundCommand;
import ghidra.framework.model.DomainObject; import ghidra.framework.model.DomainObject;
import ghidra.framework.model.UndoableDomainObject;
import ghidra.framework.plugintool.PluginTool; import ghidra.framework.plugintool.PluginTool;
import ghidra.util.Msg; import ghidra.util.Msg;
import ghidra.util.Swing; import ghidra.util.Swing;
@ -35,8 +34,8 @@ import ghidra.util.task.*;
public enum BackgroundUtils { public enum BackgroundUtils {
; ;
public static class AsyncBackgroundCommand<T extends UndoableDomainObject> public static class AsyncBackgroundCommand<T extends DomainObject>
extends BackgroundCommand { extends BackgroundCommand<T> {
private CompletableFuture<?> promise; private CompletableFuture<?> promise;
private final CancelledListener cancelledListener = this::cancelled; private final CancelledListener cancelledListener = this::cancelled;
@ -53,9 +52,8 @@ public enum BackgroundUtils {
} }
@Override @Override
@SuppressWarnings("unchecked") public boolean applyTo(T obj, TaskMonitor monitor) {
public boolean applyTo(DomainObject obj, TaskMonitor monitor) { promise = futureProducer.apply(obj, monitor);
promise = futureProducer.apply((T) obj, monitor);
monitor.addCancelledListener(cancelledListener); monitor.addCancelledListener(cancelledListener);
try { try {
promise.get(); promise.get();
@ -103,8 +101,8 @@ public enum BackgroundUtils {
* @param futureProducer a function to start the task * @param futureProducer a function to start the task
* @return a future which completes when the task is finished. * @return a future which completes when the task is finished.
*/ */
public static <T extends UndoableDomainObject> AsyncBackgroundCommand<T> async(PluginTool tool, public static <T extends DomainObject> AsyncBackgroundCommand<T> async(PluginTool tool, T obj,
T obj, String name, boolean hasProgress, boolean canCancel, boolean isModal, String name, boolean hasProgress, boolean canCancel, boolean isModal,
BiFunction<T, TaskMonitor, CompletableFuture<?>> futureProducer) { BiFunction<T, TaskMonitor, CompletableFuture<?>> futureProducer) {
AsyncBackgroundCommand<T> cmd = AsyncBackgroundCommand<T> cmd =
new AsyncBackgroundCommand<>(name, hasProgress, canCancel, isModal, futureProducer); 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 * 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 * 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 * {@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. * 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 * 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. * they would have to share a single task monitor component.
@ -172,14 +170,14 @@ public enum BackgroundUtils {
private final PluginTool tool; private final PluginTool tool;
private final String name; private final String name;
private final UndoableDomainObject obj; private final DomainObject obj;
private final int delay; private final int delay;
private final EnumSet<TaskOpt> opts; private final EnumSet<TaskOpt> opts;
private TaskMonitor lastMonitor; private TaskMonitor lastMonitor;
public PluginToolExecutorService(PluginTool tool, String name, UndoableDomainObject obj, public PluginToolExecutorService(PluginTool tool, String name, DomainObject obj, int delay,
int delay, TaskOpt... opts) { TaskOpt... opts) {
this.tool = tool; this.tool = tool;
this.name = name; this.name = name;
this.obj = obj; this.obj = obj;
@ -223,10 +221,8 @@ public enum BackgroundUtils {
} }
protected void executeForeground(Runnable command) { protected void executeForeground(Runnable command) {
Task task = new Task(name, Task task = new Task(name, opts.contains(TaskOpt.CAN_CANCEL),
opts.contains(TaskOpt.CAN_CANCEL), opts.contains(TaskOpt.HAS_PROGRESS), opts.contains(TaskOpt.IS_MODAL)) {
opts.contains(TaskOpt.HAS_PROGRESS),
opts.contains(TaskOpt.IS_MODAL)) {
@Override @Override
public void run(TaskMonitor monitor) throws CancelledException { public void run(TaskMonitor monitor) throws CancelledException {
lastMonitor = monitor; lastMonitor = monitor;
@ -237,10 +233,8 @@ public enum BackgroundUtils {
} }
protected void executeBackground(Runnable command) { protected void executeBackground(Runnable command) {
BackgroundCommand cmd = new BackgroundCommand(name, BackgroundCommand cmd = new BackgroundCommand(name, opts.contains(TaskOpt.HAS_PROGRESS),
opts.contains(TaskOpt.HAS_PROGRESS), opts.contains(TaskOpt.CAN_CANCEL), opts.contains(TaskOpt.IS_MODAL)) {
opts.contains(TaskOpt.CAN_CANCEL),
opts.contains(TaskOpt.IS_MODAL)) {
@Override @Override
public boolean applyTo(DomainObject obj, TaskMonitor monitor) { public boolean applyTo(DomainObject obj, TaskMonitor monitor) {
lastMonitor = monitor; lastMonitor = monitor;

View file

@ -17,10 +17,10 @@ package ghidra.app.plugin.core.debug.utils;
import ghidra.async.AsyncDebouncer; import ghidra.async.AsyncDebouncer;
import ghidra.async.AsyncTimer; import ghidra.async.AsyncTimer;
import ghidra.framework.model.UndoableDomainObject; import ghidra.framework.model.DomainObject;
import ghidra.util.Msg; import ghidra.util.Msg;
public class DefaultTransactionCoalescer<T extends UndoableDomainObject, U extends AutoCloseable> public class DefaultTransactionCoalescer<T extends DomainObject, U extends AutoCloseable>
implements TransactionCoalescer { implements TransactionCoalescer {
protected class Coalescer { protected class Coalescer {

View file

@ -17,11 +17,10 @@ package ghidra.app.plugin.core.debug.utils;
import java.util.function.BiFunction; import java.util.function.BiFunction;
import ghidra.framework.model.UndoableDomainObject; import ghidra.framework.model.DomainObject;
public interface TransactionCoalescer { public interface TransactionCoalescer {
public interface TxFactory<T extends UndoableDomainObject, U> public interface TxFactory<T extends DomainObject, U> extends BiFunction<T, String, U> {
extends BiFunction<T, String, U> {
} }
public interface CoalescedTx extends AutoCloseable { public interface CoalescedTx extends AutoCloseable {

View file

@ -197,9 +197,8 @@ public class DebuggerDisassemblyTest extends AbstractGhidraHeadedDebuggerTest {
DBTraceMemoryManager memory = tb.trace.getMemoryManager(); DBTraceMemoryManager memory = tb.trace.getMemoryManager();
if (pcInStack) { if (pcInStack) {
DBTraceObject objFrame = DBTraceObject objFrame = objects
objects.createObject( .createObject(TraceObjectKeyPath.parse("Targets[0].Threads[0].Stack[0]"));
TraceObjectKeyPath.parse("Targets[0].Threads[0].Stack[0]"));
objFrame.insert(zeroOn, ConflictResolution.DENY); objFrame.insert(zeroOn, ConflictResolution.DENY);
TraceObjectStackFrame frame = objFrame.queryInterface(TraceObjectStackFrame.class); TraceObjectStackFrame frame = objFrame.queryInterface(TraceObjectStackFrame.class);
frame.setProgramCounter(zeroOn, tb.addr(offset)); frame.setProgramCounter(zeroOn, tb.addr(offset));
@ -208,8 +207,8 @@ public class DebuggerDisassemblyTest extends AbstractGhidraHeadedDebuggerTest {
objects.createObject( objects.createObject(
TraceObjectKeyPath.parse("Targets[0].Threads[0].Stack[0].Registers")) TraceObjectKeyPath.parse("Targets[0].Threads[0].Stack[0].Registers"))
.insert(zeroOn, ConflictResolution.DENY); .insert(zeroOn, ConflictResolution.DENY);
TraceObjectThread thread = objects.getObjectByCanonicalPath( TraceObjectThread thread = objects
TraceObjectKeyPath.parse("Targets[0].Threads[0]")) .getObjectByCanonicalPath(TraceObjectKeyPath.parse("Targets[0].Threads[0]"))
.queryInterface(TraceObjectThread.class); .queryInterface(TraceObjectThread.class);
traceManager.activateThread(thread); traceManager.activateThread(thread);
DBTraceMemorySpace regs = DBTraceMemorySpace regs =
@ -248,8 +247,8 @@ public class DebuggerDisassemblyTest extends AbstractGhidraHeadedDebuggerTest {
} }
} }
protected void createLegacyTrace(String langID, long offset, protected void createLegacyTrace(String langID, long offset, Supplier<ByteBuffer> byteSupplier)
Supplier<ByteBuffer> byteSupplier) throws Throwable { throws Throwable {
createAndOpenTrace(langID); createAndOpenTrace(langID);
try (Transaction tx = tb.startTransaction()) { try (Transaction tx = tb.startTransaction()) {
@ -358,8 +357,8 @@ public class DebuggerDisassemblyTest extends AbstractGhidraHeadedDebuggerTest {
try (Transaction tx = program.openTransaction("Load")) { try (Transaction tx = program.openTransaction("Load")) {
start = program.getAddressFactory().getDefaultAddressSpace().getAddress(0x00400000); start = program.getAddressFactory().getDefaultAddressSpace().getAddress(0x00400000);
program.getMemory() program.getMemory()
.createInitializedBlock(".text", start, .createInitializedBlock(".text", start, new ByteArrayInputStream(arr("ebffc0")),
new ByteArrayInputStream(arr("ebffc0")), 3, monitor, false); 3, monitor, false);
} }
intoProject(program); intoProject(program);
@ -654,7 +653,7 @@ public class DebuggerDisassemblyTest extends AbstractGhidraHeadedDebuggerTest {
new AddressSet(start, start.addWrap(1))); new AddressSet(start, start.addWrap(1)));
dis.setInitialContext(DebuggerDisassemblerPlugin.deriveAlternativeDefaultContext( dis.setInitialContext(DebuggerDisassemblerPlugin.deriveAlternativeDefaultContext(
tb.language, new LanguageID("ARM:LE:32:v8T"), start)); 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); waitForDomainObject(tb.trace);
@ -715,11 +714,11 @@ public class DebuggerDisassemblyTest extends AbstractGhidraHeadedDebuggerTest {
TraceGuestPlatform guest = TraceGuestPlatform guest =
Unique.assertOne(tb.trace.getPlatformManager().getGuestPlatforms()); Unique.assertOne(tb.trace.getPlatformManager().getGuestPlatforms());
try (Transaction tx = tb.startTransaction()) { try (Transaction tx = tb.startTransaction()) {
TraceDisassembleCommand dis = new TraceDisassembleCommand(guest, start, TraceDisassembleCommand dis =
new AddressSet(start, start.addWrap(1))); new TraceDisassembleCommand(guest, start, new AddressSet(start, start.addWrap(1)));
dis.setInitialContext(DebuggerDisassemblerPlugin.deriveAlternativeDefaultContext( dis.setInitialContext(DebuggerDisassemblerPlugin.deriveAlternativeDefaultContext(
guest.getLanguage(), new LanguageID("ARM:LE:32:v8T"), start)); 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); waitForDomainObject(tb.trace);

View file

@ -190,8 +190,7 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest {
function.updateFunction("__cdecl", function.updateFunction("__cdecl",
new ReturnParameterImpl(IntegerDataType.dataType, program), new ReturnParameterImpl(IntegerDataType.dataType, program),
List.of( List.of(new ParameterImpl("n", IntegerDataType.dataType, program)),
new ParameterImpl("n", IntegerDataType.dataType, program)),
FunctionUpdateType.DYNAMIC_STORAGE_FORMAL_PARAMS, true, SourceType.ANALYSIS); FunctionUpdateType.DYNAMIC_STORAGE_FORMAL_PARAMS, true, SourceType.ANALYSIS);
function.addLocalVariable( function.addLocalVariable(
new LocalVariableImpl("i", IntegerDataType.dataType, -8, program), new LocalVariableImpl("i", IntegerDataType.dataType, -8, program),
@ -263,14 +262,12 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest {
function.updateFunction("__cdecl", function.updateFunction("__cdecl",
new ReturnParameterImpl(UnsignedIntegerDataType.dataType, program), new ReturnParameterImpl(UnsignedIntegerDataType.dataType, program),
List.of( List.of(new ParameterImpl("n", UnsignedIntegerDataType.dataType, program)),
new ParameterImpl("n", UnsignedIntegerDataType.dataType, program)),
FunctionUpdateType.DYNAMIC_STORAGE_FORMAL_PARAMS, true, SourceType.ANALYSIS); FunctionUpdateType.DYNAMIC_STORAGE_FORMAL_PARAMS, true, SourceType.ANALYSIS);
// NOTE: The decompiler doesn't actually use sum.... For some reason, it re-uses n // 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 // Still, in the tests, I can use uVar1 (EAX) as a register variable
function.addLocalVariable( function.addLocalVariable(new LocalVariableImpl("sum", 0,
new LocalVariableImpl("sum", 0, UnsignedIntegerDataType.dataType, register("EDX"), UnsignedIntegerDataType.dataType, register("EDX"), program),
program),
SourceType.USER_DEFINED); SourceType.USER_DEFINED);
Instruction ins = program.getListing().getInstructionAt(stackRefInstr); Instruction ins = program.getListing().getInstructionAt(stackRefInstr);
@ -501,18 +498,15 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest {
.createFunction("fillStruct", funcInstr, .createFunction("fillStruct", funcInstr,
new AddressSet(funcInstr, end.previous()), SourceType.USER_DEFINED); new AddressSet(funcInstr, end.previous()), SourceType.USER_DEFINED);
funFillStruct.updateFunction("__cdecl", null, funFillStruct.updateFunction("__cdecl", null,
List.of( List.of(new ParameterImpl("s", new PointerDataType(structure), program)),
new ParameterImpl("s", new PointerDataType(structure), program)),
FunctionUpdateType.DYNAMIC_STORAGE_FORMAL_PARAMS, true, SourceType.ANALYSIS); FunctionUpdateType.DYNAMIC_STORAGE_FORMAL_PARAMS, true, SourceType.ANALYSIS);
Function main = program.getFunctionManager() Function main = program.getFunctionManager()
.createFunction("main", entry, new AddressSet(entry, funcInstr.previous()), .createFunction("main", entry, new AddressSet(entry, funcInstr.previous()),
SourceType.USER_DEFINED); SourceType.USER_DEFINED);
main.updateFunction("__cdecl", main.updateFunction("__cdecl", new ReturnParameterImpl(DWordDataType.dataType, program),
new ReturnParameterImpl(DWordDataType.dataType, program),
FunctionUpdateType.DYNAMIC_STORAGE_FORMAL_PARAMS, true, SourceType.ANALYSIS); FunctionUpdateType.DYNAMIC_STORAGE_FORMAL_PARAMS, true, SourceType.ANALYSIS);
main.addLocalVariable( main.addLocalVariable(new LocalVariableImpl("myStack", structure, -8, program),
new LocalVariableImpl("myStack", structure, -8, program),
SourceType.ANALYSIS); SourceType.ANALYSIS);
return main; return main;
} }
@ -581,16 +575,14 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest {
.createFunction("fillStruct", funcInstr, .createFunction("fillStruct", funcInstr,
new AddressSet(funcInstr, end.previous()), SourceType.USER_DEFINED); new AddressSet(funcInstr, end.previous()), SourceType.USER_DEFINED);
funFillStruct.updateFunction("__cdecl", null, funFillStruct.updateFunction("__cdecl", null,
List.of( List.of(new ParameterImpl("s", new PointerDataType(structure), program),
new ParameterImpl("s", new PointerDataType(structure), program),
new ParameterImpl("i", IntegerDataType.dataType, program)), new ParameterImpl("i", IntegerDataType.dataType, program)),
FunctionUpdateType.DYNAMIC_STORAGE_FORMAL_PARAMS, true, SourceType.ANALYSIS); FunctionUpdateType.DYNAMIC_STORAGE_FORMAL_PARAMS, true, SourceType.ANALYSIS);
Function main = program.getFunctionManager() Function main = program.getFunctionManager()
.createFunction("main", entry, new AddressSet(entry, funcInstr.previous()), .createFunction("main", entry, new AddressSet(entry, funcInstr.previous()),
SourceType.USER_DEFINED); SourceType.USER_DEFINED);
main.updateFunction("__cdecl", main.updateFunction("__cdecl", new ReturnParameterImpl(DWordDataType.dataType, program),
new ReturnParameterImpl(DWordDataType.dataType, program),
FunctionUpdateType.DYNAMIC_STORAGE_FORMAL_PARAMS, true, SourceType.ANALYSIS); FunctionUpdateType.DYNAMIC_STORAGE_FORMAL_PARAMS, true, SourceType.ANALYSIS);
return main; return main;
} }
@ -614,10 +606,7 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest {
UnwindInfo infoAtBody = ua.computeUnwindInfo(bodyInstr, monitor); UnwindInfo infoAtBody = ua.computeUnwindInfo(bodyInstr, monitor);
assertEquals(new UnwindInfo(function, -20L, 4L, stack(0), assertEquals(new UnwindInfo(function, -20L, 4L, stack(0),
Map.of( Map.of(register("EBP"), stack(-4)), new StackUnwindWarningSet(), null), infoAtBody);
register("EBP"), stack(-4)),
new StackUnwindWarningSet(), null),
infoAtBody);
} }
@Test @Test
@ -640,11 +629,9 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest {
infoAtEntry); infoAtEntry);
UnwindInfo infoAtBody = ua.computeUnwindInfo(bodyInstr, monitor); UnwindInfo infoAtBody = ua.computeUnwindInfo(bodyInstr, monitor);
assertEquals(new UnwindInfo(function, -20L, 4L, stack(0), assertEquals(
Map.of( new UnwindInfo(function, -20L, 4L, stack(0), Map.of(register("EBP"), stack(-4)),
register("EBP"), stack(-4)), new StackUnwindWarningSet(new UnspecifiedConventionStackUnwindWarning(myExtern),
new StackUnwindWarningSet(
new UnspecifiedConventionStackUnwindWarning(myExtern),
new UnknownPurgeStackUnwindWarning(myExtern)), new UnknownPurgeStackUnwindWarning(myExtern)),
null), null),
infoAtBody); infoAtBody);
@ -670,11 +657,8 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest {
UnwindInfo infoAtBody = ua.computeUnwindInfo(bodyInstr, monitor); UnwindInfo infoAtBody = ua.computeUnwindInfo(bodyInstr, monitor);
DataType ptr2Undef = new PointerDataType(DataType.DEFAULT, program.getDataTypeManager()); DataType ptr2Undef = new PointerDataType(DataType.DEFAULT, program.getDataTypeManager());
assertEquals(new UnwindInfo(function, -20L, 4L, stack(0), assertEquals(new UnwindInfo(function, -20L, 4L, stack(0),
Map.of( Map.of(register("EBP"), stack(-4)),
register("EBP"), stack(-4)), new StackUnwindWarningSet(new UnexpectedTargetTypeStackUnwindWarning(ptr2Undef)), null),
new StackUnwindWarningSet(
new UnexpectedTargetTypeStackUnwindWarning(ptr2Undef)),
null),
infoAtBody); infoAtBody);
} }
@ -684,8 +668,7 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest {
addPlugin(tool, DebuggerListingPlugin.class); addPlugin(tool, DebuggerListingPlugin.class);
addPlugin(tool, DisassemblerPlugin.class); addPlugin(tool, DisassemblerPlugin.class);
addPlugin(tool, DecompilePlugin.class); addPlugin(tool, DecompilePlugin.class);
DebuggerControlService editingService = DebuggerControlService editingService = addPlugin(tool, DebuggerControlServicePlugin.class);
addPlugin(tool, DebuggerControlServicePlugin.class);
DebuggerEmulationService emuService = addPlugin(tool, DebuggerEmulationServicePlugin.class); DebuggerEmulationService emuService = addPlugin(tool, DebuggerEmulationServicePlugin.class);
Function function = createSumSquaresProgramX86_32(); Function function = createSumSquaresProgramX86_32();
@ -744,8 +727,7 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest {
addPlugin(tool, DebuggerListingPlugin.class); addPlugin(tool, DebuggerListingPlugin.class);
addPlugin(tool, DisassemblerPlugin.class); addPlugin(tool, DisassemblerPlugin.class);
addPlugin(tool, DecompilePlugin.class); addPlugin(tool, DecompilePlugin.class);
DebuggerControlService editingService = DebuggerControlService editingService = addPlugin(tool, DebuggerControlServicePlugin.class);
addPlugin(tool, DebuggerControlServicePlugin.class);
DebuggerEmulationService emuService = addPlugin(tool, DebuggerEmulationServicePlugin.class); DebuggerEmulationService emuService = addPlugin(tool, DebuggerEmulationServicePlugin.class);
Function function = createFibonacciProgramX86_32(); Function function = createFibonacciProgramX86_32();
@ -775,13 +757,12 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest {
TraceBreakpoint bptUnwind; TraceBreakpoint bptUnwind;
try (Transaction tx = tb.startTransaction()) { try (Transaction tx = tb.startTransaction()) {
bptUnwind = tb.trace.getBreakpointManager() bptUnwind = tb.trace.getBreakpointManager()
.addBreakpoint("Breakpoints[0]", Lifespan.nowOn(0), retInstr, .addBreakpoint("Breakpoints[0]", Lifespan.nowOn(0), retInstr, Set.of(),
Set.of(),
Set.of(TraceBreakpointKind.SW_EXECUTE), true, "unwind stack"); Set.of(TraceBreakpointKind.SW_EXECUTE), true, "unwind stack");
tb.trace.getBreakpointManager() tb.trace.getBreakpointManager()
.addBreakpoint("Breakpoints[1]", Lifespan.nowOn(0), tb.addr(0xdeadbeef), .addBreakpoint("Breakpoints[1]", Lifespan.nowOn(0), tb.addr(0xdeadbeef),
Set.of(), Set.of(), Set.of(TraceBreakpointKind.SW_EXECUTE), true,
Set.of(TraceBreakpointKind.SW_EXECUTE), true, "capture return value"); "capture return value");
} }
EmulationResult result = emuService.run(atSetup.getPlatform(), atSetup.getTime(), monitor, EmulationResult result = emuService.run(atSetup.getPlatform(), atSetup.getTime(), monitor,
@ -916,8 +897,7 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest {
try (Transaction tx = tb.startTransaction()) { try (Transaction tx = tb.startTransaction()) {
tb.trace.getBreakpointManager() tb.trace.getBreakpointManager()
.addBreakpoint("Breakpoints[0]", Lifespan.nowOn(0), retInstr, .addBreakpoint("Breakpoints[0]", Lifespan.nowOn(0), retInstr, Set.of(),
Set.of(),
Set.of(TraceBreakpointKind.SW_EXECUTE), true, "unwind stack"); Set.of(TraceBreakpointKind.SW_EXECUTE), true, "unwind stack");
} }
@ -957,8 +937,7 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest {
try (Transaction tx = tb.startTransaction()) { try (Transaction tx = tb.startTransaction()) {
tb.trace.getBreakpointManager() tb.trace.getBreakpointManager()
.addBreakpoint("Breakpoints[0]", Lifespan.nowOn(0), retInstr, .addBreakpoint("Breakpoints[0]", Lifespan.nowOn(0), retInstr, Set.of(),
Set.of(),
Set.of(TraceBreakpointKind.SW_EXECUTE), true, "unwind stack"); Set.of(TraceBreakpointKind.SW_EXECUTE), true, "unwind stack");
} }
@ -999,8 +978,7 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest {
try (Transaction tx = tb.startTransaction()) { try (Transaction tx = tb.startTransaction()) {
tb.trace.getBreakpointManager() tb.trace.getBreakpointManager()
.addBreakpoint("Breakpoints[0]", Lifespan.nowOn(0), retInstr, .addBreakpoint("Breakpoints[0]", Lifespan.nowOn(0), retInstr, Set.of(),
Set.of(),
Set.of(TraceBreakpointKind.SW_EXECUTE), true, "unwind stack"); Set.of(TraceBreakpointKind.SW_EXECUTE), true, "unwind stack");
} }
@ -1041,8 +1019,7 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest {
try (Transaction tx = tb.startTransaction()) { try (Transaction tx = tb.startTransaction()) {
tb.trace.getBreakpointManager() tb.trace.getBreakpointManager()
.addBreakpoint("Breakpoints[0]", Lifespan.nowOn(0), retInstr, .addBreakpoint("Breakpoints[0]", Lifespan.nowOn(0), retInstr, Set.of(),
Set.of(),
Set.of(TraceBreakpointKind.SW_EXECUTE), true, "unwind stack"); Set.of(TraceBreakpointKind.SW_EXECUTE), true, "unwind stack");
} }
@ -1166,8 +1143,8 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest {
FieldLocation fieldLocation, Field field) throws Throwable { FieldLocation fieldLocation, Field field) throws Throwable {
VariableValueTable table = new VariableValueTable(); VariableValueTable table = new VariableValueTable();
StackUnwindWarningSet warnings = new StackUnwindWarningSet(); StackUnwindWarningSet warnings = new StackUnwindWarningSet();
waitOn(valuesService.fillVariableValueTable(table, programLocation, current, waitOn(valuesService.fillVariableValueTable(table, programLocation, current, fieldLocation,
fieldLocation, field, warnings)); field, warnings));
table.add(new WarningsRow(warnings)); table.add(new WarningsRow(warnings));
return table; return table;
} }
@ -1182,16 +1159,12 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest {
VariableValueTable table = getVariableValueTable(valuesService, loc.pLoc, VariableValueTable table = getVariableValueTable(valuesService, loc.pLoc,
traceManager.getCurrent(), loc.fLoc, loc.field); traceManager.getCurrent(), loc.fLoc, loc.field);
assertTable(Map.of( assertTable(Map.of(RowKey.NAME, "Name: n", RowKey.FRAME,
RowKey.NAME, "Name: n", "Frame: 0 fib pc=0040002c sp=00004ff4 base=00004ff4", RowKey.STORAGE,
RowKey.FRAME, "Frame: 0 fib pc=0040002c sp=00004ff4 base=00004ff4", "Storage: Stack[0x4]:4", RowKey.TYPE, "Type: uint", RowKey.LOCATION,
RowKey.STORAGE, "Storage: Stack[0x4]:4", "Location: 00004ff8:4", RowKey.BYTES, "Bytes: (KNOWN) 01 00 00 00", RowKey.INTEGER,
RowKey.TYPE, "Type: uint", "Integer: (KNOWN) 1", RowKey.VALUE, "Value: (KNOWN) 1h", RowKey.WARNINGS, "IGNORED"),
RowKey.LOCATION, "Location: 00004ff8:4", table);
RowKey.BYTES, "Bytes: (KNOWN) 01 00 00 00",
RowKey.INTEGER, "Integer: (KNOWN) 1",
RowKey.VALUE, "Value: (KNOWN) 1h",
RowKey.WARNINGS, "IGNORED"), table);
} }
@Test @Test
@ -1204,15 +1177,11 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest {
VariableValueTable table = getVariableValueTable(valuesService, loc.pLoc, VariableValueTable table = getVariableValueTable(valuesService, loc.pLoc,
traceManager.getCurrent(), loc.fLoc, loc.field); traceManager.getCurrent(), loc.fLoc, loc.field);
assertTable(Map.of( assertTable(Map.of(RowKey.NAME, "Name: sum", RowKey.FRAME,
RowKey.NAME, "Name: sum", "Frame: 0 fib pc=0040002c sp=00004ff4 base=00004ff4", RowKey.STORAGE, "Storage: EDX:4",
RowKey.FRAME, "Frame: 0 fib pc=0040002c sp=00004ff4 base=00004ff4", RowKey.TYPE, "Type: uint", RowKey.LOCATION, "Location: EDX:4", RowKey.INTEGER,
RowKey.STORAGE, "Storage: EDX:4", "Integer: (UNKNOWN) 0", RowKey.VALUE, "Value: (UNKNOWN) 0h", RowKey.WARNINGS,
RowKey.TYPE, "Type: uint", "IGNORED"), table);
RowKey.LOCATION, "Location: EDX:4",
RowKey.INTEGER, "Integer: (UNKNOWN) 0",
RowKey.VALUE, "Value: (UNKNOWN) 0h",
RowKey.WARNINGS, "IGNORED"), table);
} }
@Test @Test
@ -1225,15 +1194,11 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest {
VariableValueTable table = getVariableValueTable(valuesService, loc.pLoc, VariableValueTable table = getVariableValueTable(valuesService, loc.pLoc,
traceManager.getCurrent(), loc.fLoc, loc.field); traceManager.getCurrent(), loc.fLoc, loc.field);
assertTable(Map.of( assertTable(Map.of(RowKey.NAME, "Name: <RETURN>", RowKey.FRAME,
RowKey.NAME, "Name: <RETURN>", "Frame: 0 fib pc=0040002c sp=00004ff4 base=00004ff4", RowKey.STORAGE, "Storage: EAX:4",
RowKey.FRAME, "Frame: 0 fib pc=0040002c sp=00004ff4 base=00004ff4", RowKey.TYPE, "Type: uint", RowKey.LOCATION, "Location: EAX:4", RowKey.INTEGER,
RowKey.STORAGE, "Storage: EAX:4", "Integer: (KNOWN) 1", RowKey.VALUE, "Value: (KNOWN) 1h", RowKey.WARNINGS, "IGNORED"),
RowKey.TYPE, "Type: uint", table);
RowKey.LOCATION, "Location: EAX:4",
RowKey.INTEGER, "Integer: (KNOWN) 1",
RowKey.VALUE, "Value: (KNOWN) 1h",
RowKey.WARNINGS, "IGNORED"), table);
} }
@Test @Test
@ -1247,16 +1212,11 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest {
VariableValueTable table = getVariableValueTable(valuesService, loc.pLoc, VariableValueTable table = getVariableValueTable(valuesService, loc.pLoc,
traceManager.getCurrent(), loc.fLoc, loc.field); traceManager.getCurrent(), loc.fLoc, loc.field);
assertTable(Map.of( assertTable(Map.of(RowKey.NAME, "Name: myGlobal", RowKey.STORAGE, "Storage: 00600000:4",
RowKey.NAME, "Name: myGlobal", RowKey.TYPE, "Type: int", RowKey.LOCATION, "Location: 00600000:4", RowKey.BYTES,
RowKey.STORAGE, "Storage: 00600000:4", "Bytes: (KNOWN) ef be ad de", RowKey.INTEGER, """
RowKey.TYPE, "Type: int",
RowKey.LOCATION, "Location: 00600000:4",
RowKey.BYTES, "Bytes: (KNOWN) ef be ad de",
RowKey.INTEGER, """
Integer: (KNOWN) 3735928559, 0xdeadbeef Integer: (KNOWN) 3735928559, 0xdeadbeef
-559038737, -0x21524111""", -559038737, -0x21524111""", RowKey.VALUE, "Value: (KNOWN) DEADBEEFh",
RowKey.VALUE, "Value: (KNOWN) DEADBEEFh",
RowKey.WARNINGS, "IGNORED"), table); RowKey.WARNINGS, "IGNORED"), table);
} }
@ -1269,17 +1229,17 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest {
Address dynamicAddress = dynLoc.getAddress(); Address dynamicAddress = dynLoc.getAddress();
try (Transaction tx = tb.startTransaction()) { try (Transaction tx = tb.startTransaction()) {
int length = stIns.getLength(); int length = stIns.getLength();
assertEquals(length, tb.trace.getMemoryManager() assertEquals(length,
tb.trace.getMemoryManager()
.putBytes(current.getSnap(), dynamicAddress, .putBytes(current.getSnap(), dynamicAddress,
ByteBuffer.wrap(stIns.getBytes()))); ByteBuffer.wrap(stIns.getBytes())));
new TraceDisassembleCommand(current.getPlatform(), dynamicAddress, new TraceDisassembleCommand(current.getPlatform(), dynamicAddress,
new AddressSet(dynamicAddress, dynamicAddress.add(length - 1))) new AddressSet(dynamicAddress, dynamicAddress.add(length - 1)))
.applyToTyped(current.getView(), monitor); .applyTo(current.getView(), monitor);
} }
waitForDomainObject(tb.trace); waitForDomainObject(tb.trace);
return Objects.requireNonNull(tb.trace.getCodeManager() return Objects.requireNonNull(
.instructions() tb.trace.getCodeManager().instructions().getAt(current.getViewSnap(), dynamicAddress));
.getAt(current.getViewSnap(), dynamicAddress));
} }
@Test @Test
@ -1295,16 +1255,11 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest {
VariableValueTable table = getVariableValueTable(valuesService, loc.pLoc, VariableValueTable table = getVariableValueTable(valuesService, loc.pLoc,
traceManager.getCurrent(), loc.fLoc, loc.field); traceManager.getCurrent(), loc.fLoc, loc.field);
assertTable(Map.of( assertTable(Map.of(RowKey.NAME, "Name: myGlobal", RowKey.STORAGE, "Storage: 00600000:4",
RowKey.NAME, "Name: myGlobal", RowKey.TYPE, "Type: int", RowKey.LOCATION, "Location: 00600000:4", RowKey.BYTES,
RowKey.STORAGE, "Storage: 00600000:4", "Bytes: (KNOWN) ef be ad de", RowKey.INTEGER, """
RowKey.TYPE, "Type: int",
RowKey.LOCATION, "Location: 00600000:4",
RowKey.BYTES, "Bytes: (KNOWN) ef be ad de",
RowKey.INTEGER, """
Integer: (KNOWN) 3735928559, 0xdeadbeef Integer: (KNOWN) 3735928559, 0xdeadbeef
-559038737, -0x21524111""", -559038737, -0x21524111""", RowKey.VALUE, "Value: (KNOWN) DEADBEEFh",
RowKey.VALUE, "Value: (KNOWN) DEADBEEFh",
RowKey.WARNINGS, "IGNORED"), table); RowKey.WARNINGS, "IGNORED"), table);
} }
@ -1319,16 +1274,12 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest {
VariableValueTable table = getVariableValueTable(valuesService, loc.pLoc, VariableValueTable table = getVariableValueTable(valuesService, loc.pLoc,
traceManager.getCurrent(), loc.fLoc, loc.field); traceManager.getCurrent(), loc.fLoc, loc.field);
assertTable(Map.of( assertTable(Map.of(RowKey.NAME, "Name: n", RowKey.FRAME,
RowKey.NAME, "Name: n", "Frame: 0 fib pc=0040002c sp=00004ff4 base=00004ff4", RowKey.STORAGE,
RowKey.FRAME, "Frame: 0 fib pc=0040002c sp=00004ff4 base=00004ff4", "Storage: Stack[0x4]:4", RowKey.TYPE, "Type: uint", RowKey.LOCATION,
RowKey.STORAGE, "Storage: Stack[0x4]:4", "Location: 00004ff8:4", RowKey.BYTES, "Bytes: (KNOWN) 01 00 00 00", RowKey.INTEGER,
RowKey.TYPE, "Type: uint", "Integer: (KNOWN) 1", RowKey.VALUE, "Value: (KNOWN) 1h", RowKey.WARNINGS, "IGNORED"),
RowKey.LOCATION, "Location: 00004ff8:4", table);
RowKey.BYTES, "Bytes: (KNOWN) 01 00 00 00",
RowKey.INTEGER, "Integer: (KNOWN) 1",
RowKey.VALUE, "Value: (KNOWN) 1h",
RowKey.WARNINGS, "IGNORED"), table);
} }
@Test @Test
@ -1342,15 +1293,11 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest {
VariableValueTable table = getVariableValueTable(valuesService, loc.pLoc, VariableValueTable table = getVariableValueTable(valuesService, loc.pLoc,
traceManager.getCurrent(), loc.fLoc, loc.field); traceManager.getCurrent(), loc.fLoc, loc.field);
assertTable(Map.of( assertTable(Map.of(RowKey.NAME, "Name: sum", RowKey.FRAME,
RowKey.NAME, "Name: sum", "Frame: 0 fib pc=0040002c sp=00004ff4 base=00004ff4", RowKey.STORAGE, "Storage: EDX:4",
RowKey.FRAME, "Frame: 0 fib pc=0040002c sp=00004ff4 base=00004ff4", RowKey.TYPE, "Type: uint", RowKey.LOCATION, "Location: EDX:4", RowKey.INTEGER,
RowKey.STORAGE, "Storage: EDX:4", "Integer: (UNKNOWN) 0", RowKey.VALUE, "Value: (UNKNOWN) 0h", RowKey.WARNINGS,
RowKey.TYPE, "Type: uint", "IGNORED"), table);
RowKey.LOCATION, "Location: EDX:4",
RowKey.INTEGER, "Integer: (UNKNOWN) 0",
RowKey.VALUE, "Value: (UNKNOWN) 0h",
RowKey.WARNINGS, "IGNORED"), table);
} }
@Test @Test
@ -1367,11 +1314,9 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest {
VariableValueTable table = getVariableValueTable(valuesService, loc.pLoc, VariableValueTable table = getVariableValueTable(valuesService, loc.pLoc,
traceManager.getCurrent(), loc.fLoc, loc.field); traceManager.getCurrent(), loc.fLoc, loc.field);
assertTable(Map.of( assertTable(Map.of(RowKey.NAME, "Name: EBP", RowKey.FRAME,
RowKey.NAME, "Name: EBP", "Frame: 2 fib pc=00400013 sp=00004ff8 base=00005000", RowKey.LOCATION,
RowKey.FRAME, "Frame: 2 fib pc=00400013 sp=00004ff8 base=00005000", "Location: 00004ff0:4", RowKey.INTEGER, "Integer: (KNOWN) 20476, 0x4ffc",
RowKey.LOCATION, "Location: 00004ff0:4",
RowKey.INTEGER, "Integer: (KNOWN) 20476, 0x4ffc",
RowKey.WARNINGS, "IGNORED"), table); RowKey.WARNINGS, "IGNORED"), table);
} }
@ -1388,9 +1333,7 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest {
VariableValueTable table = getVariableValueTable(valuesService, loc.pLoc, VariableValueTable table = getVariableValueTable(valuesService, loc.pLoc,
traceManager.getCurrent(), loc.fLoc, loc.field); traceManager.getCurrent(), loc.fLoc, loc.field);
assertTable(Map.of( assertTable(Map.of(RowKey.NAME, "Name: EDX", RowKey.INTEGER, "Integer: (UNKNOWN) 0",
RowKey.NAME, "Name: EDX",
RowKey.INTEGER, "Integer: (UNKNOWN) 0",
RowKey.WARNINGS, "IGNORED"), table); RowKey.WARNINGS, "IGNORED"), table);
} }
@ -1495,16 +1438,11 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest {
VariableValueTable table = getVariableValueTable(valuesService, loc.pLoc, VariableValueTable table = getVariableValueTable(valuesService, loc.pLoc,
traceManager.getCurrent(), loc.fLoc, loc.field); traceManager.getCurrent(), loc.fLoc, loc.field);
assertTable(Map.of( assertTable(Map.of(RowKey.NAME, "Name: myGlobal", RowKey.STORAGE, "Storage: 00600000:4",
RowKey.NAME, "Name: myGlobal", RowKey.TYPE, "Type: int", RowKey.LOCATION, "Location: 00600000:4", RowKey.BYTES,
RowKey.STORAGE, "Storage: 00600000:4", "Bytes: (KNOWN) ef be ad de", RowKey.INTEGER, """
RowKey.TYPE, "Type: int",
RowKey.LOCATION, "Location: 00600000:4",
RowKey.BYTES, "Bytes: (KNOWN) ef be ad de",
RowKey.INTEGER, """
Integer: (KNOWN) 3735928559, 0xdeadbeef Integer: (KNOWN) 3735928559, 0xdeadbeef
-559038737, -0x21524111""", -559038737, -0x21524111""", RowKey.VALUE, "Value: (KNOWN) DEADBEEFh",
RowKey.VALUE, "Value: (KNOWN) DEADBEEFh",
RowKey.WARNINGS, "IGNORED"), table); RowKey.WARNINGS, "IGNORED"), table);
} }
@ -1518,16 +1456,12 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest {
VariableValueTable table = getVariableValueTable(valuesService, loc.pLoc, VariableValueTable table = getVariableValueTable(valuesService, loc.pLoc,
traceManager.getCurrent(), loc.fLoc, loc.field); traceManager.getCurrent(), loc.fLoc, loc.field);
assertTable(Map.of( assertTable(Map.of(RowKey.NAME, "Name: n", RowKey.FRAME,
RowKey.NAME, "Name: n", "Frame: 0 fib pc=0040002c sp=00004ff4 base=00004ff4", RowKey.STORAGE,
RowKey.FRAME, "Frame: 0 fib pc=0040002c sp=00004ff4 base=00004ff4", "Storage: Stack[0x4]:4", RowKey.TYPE, "Type: uint", RowKey.LOCATION,
RowKey.STORAGE, "Storage: Stack[0x4]:4", "Location: 00004ff8:4", RowKey.BYTES, "Bytes: (KNOWN) 01 00 00 00", RowKey.INTEGER,
RowKey.TYPE, "Type: uint", "Integer: (KNOWN) 1", RowKey.VALUE, "Value: (KNOWN) 1h", RowKey.WARNINGS, "IGNORED"),
RowKey.LOCATION, "Location: 00004ff8:4", table);
RowKey.BYTES, "Bytes: (KNOWN) 01 00 00 00",
RowKey.INTEGER, "Integer: (KNOWN) 1",
RowKey.VALUE, "Value: (KNOWN) 1h",
RowKey.WARNINGS, "IGNORED"), table);
} }
@Test @Test
@ -1541,15 +1475,11 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest {
VariableValueTable table = getVariableValueTable(valuesService, loc.pLoc, VariableValueTable table = getVariableValueTable(valuesService, loc.pLoc,
traceManager.getCurrent(), loc.fLoc, loc.field); traceManager.getCurrent(), loc.fLoc, loc.field);
assertTable(Map.of( assertTable(Map.of(RowKey.NAME, "Name: uVar1", RowKey.FRAME,
RowKey.NAME, "Name: uVar1", "Frame: 0 fib pc=0040002c sp=00004ff4 base=00004ff4", RowKey.STORAGE, "Storage: EAX:4",
RowKey.FRAME, "Frame: 0 fib pc=0040002c sp=00004ff4 base=00004ff4", RowKey.TYPE, "Type: uint", RowKey.LOCATION, "Location: EAX:4", RowKey.INTEGER,
RowKey.STORAGE, "Storage: EAX:4", "Integer: (KNOWN) 1", RowKey.VALUE, "Value: (KNOWN) 1h", RowKey.WARNINGS, "IGNORED"),
RowKey.TYPE, "Type: uint", table);
RowKey.LOCATION, "Location: EAX:4",
RowKey.INTEGER, "Integer: (KNOWN) 1",
RowKey.VALUE, "Value: (KNOWN) 1h",
RowKey.WARNINGS, "IGNORED"), table);
} }
@Test @Test
@ -1566,15 +1496,10 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest {
VariableValueTable table = getVariableValueTable(valuesService, loc.pLoc, VariableValueTable table = getVariableValueTable(valuesService, loc.pLoc,
traceManager.getCurrent(), loc.fLoc, loc.field); traceManager.getCurrent(), loc.fLoc, loc.field);
assertTable(Map.of( assertTable(Map.of(RowKey.NAME, "Name: myGlobal", RowKey.STORAGE, "Storage: 00600000:4",
RowKey.NAME, "Name: myGlobal", RowKey.TYPE, "Type: MyStruct", RowKey.LOCATION, "Location: 00600000:4", RowKey.BYTES,
RowKey.STORAGE, "Storage: 00600000:4", "Bytes: (KNOWN) e6 07 0c 09", RowKey.INTEGER, "Integer: (KNOWN) 151783398, 0x90c07e6",
RowKey.TYPE, "Type: MyStruct", RowKey.VALUE, "Value: (KNOWN) ", RowKey.WARNINGS, "IGNORED"), table);
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 @Test
@ -1591,14 +1516,10 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest {
VariableValueTable table = getVariableValueTable(valuesService, loc.pLoc, VariableValueTable table = getVariableValueTable(valuesService, loc.pLoc,
traceManager.getCurrent(), loc.fLoc, loc.field); traceManager.getCurrent(), loc.fLoc, loc.field);
assertTable(Map.of( assertTable(Map.of(RowKey.NAME, "Name: m", RowKey.TYPE, "Type: byte", RowKey.LOCATION,
RowKey.NAME, "Name: m", "Location: 00600002:1", RowKey.BYTES, "Bytes: (KNOWN) 0c", RowKey.INTEGER,
RowKey.TYPE, "Type: byte", "Integer: (KNOWN) 12, 0xc", RowKey.VALUE, "Value: (KNOWN) Ch", RowKey.WARNINGS,
RowKey.LOCATION, "Location: 00600002:1", "IGNORED"), table);
RowKey.BYTES, "Bytes: (KNOWN) 0c",
RowKey.INTEGER, "Integer: (KNOWN) 12, 0xc",
RowKey.VALUE, "Value: (KNOWN) Ch",
RowKey.WARNINGS, "IGNORED"), table);
} }
@Test @Test
@ -1615,16 +1536,12 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest {
VariableValueTable table = getVariableValueTable(valuesService, loc.pLoc, VariableValueTable table = getVariableValueTable(valuesService, loc.pLoc,
traceManager.getCurrent(), loc.fLoc, loc.field); traceManager.getCurrent(), loc.fLoc, loc.field);
assertTable(Map.of( assertTable(Map.of(RowKey.NAME, "Name: myStack", RowKey.FRAME,
RowKey.NAME, "Name: myStack", "Frame: 1 main pc=00400012 sp=00004fe4 base=00004ff0", RowKey.STORAGE,
RowKey.FRAME, "Frame: 1 main pc=00400012 sp=00004fe4 base=00004ff0", "Storage: Stack[-0x8]:4", RowKey.TYPE, "Type: MyStruct", RowKey.LOCATION,
RowKey.STORAGE, "Storage: Stack[-0x8]:4", "Location: 00004fe8:4", RowKey.BYTES, "Bytes: (UNKNOWN) 00 00 00 00", RowKey.INTEGER,
RowKey.TYPE, "Type: MyStruct", "Integer: (UNKNOWN) 0", RowKey.VALUE, "Value: (UNKNOWN) ", RowKey.WARNINGS, "IGNORED"),
RowKey.LOCATION, "Location: 00004fe8:4", table);
RowKey.BYTES, "Bytes: (UNKNOWN) 00 00 00 00",
RowKey.INTEGER, "Integer: (UNKNOWN) 0",
RowKey.VALUE, "Value: (UNKNOWN) ",
RowKey.WARNINGS, "IGNORED"), table);
} }
@Test @Test
@ -1641,14 +1558,10 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest {
VariableValueTable table = getVariableValueTable(valuesService, loc.pLoc, VariableValueTable table = getVariableValueTable(valuesService, loc.pLoc,
traceManager.getCurrent(), loc.fLoc, loc.field); traceManager.getCurrent(), loc.fLoc, loc.field);
assertTable(Map.of( assertTable(Map.of(RowKey.NAME, "Name: y", RowKey.FRAME,
RowKey.NAME, "Name: y", "Frame: 1 main pc=00400012 sp=00004fe4 base=00004ff0", RowKey.TYPE, "Type: word",
RowKey.FRAME, "Frame: 1 main pc=00400012 sp=00004fe4 base=00004ff0", RowKey.LOCATION, "Location: 00004fe8:2", RowKey.BYTES, "Bytes: (UNKNOWN) 00 00",
RowKey.TYPE, "Type: word", RowKey.INTEGER, "Integer: (UNKNOWN) 0", RowKey.VALUE, "Value: (UNKNOWN) 0h",
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); RowKey.WARNINGS, "IGNORED"), table);
} }
@ -1666,16 +1579,13 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest {
VariableValueTable table = getVariableValueTable(valuesService, loc.pLoc, VariableValueTable table = getVariableValueTable(valuesService, loc.pLoc,
traceManager.getCurrent(), loc.fLoc, loc.field); traceManager.getCurrent(), loc.fLoc, loc.field);
assertTable(Map.of( assertTable(Map.of(RowKey.NAME, "Name: s", RowKey.FRAME,
RowKey.NAME, "Name: s", "Frame: 0 fillStruct pc=00400041 sp=00004fe0 base=00004fe0", RowKey.STORAGE,
RowKey.FRAME, "Frame: 0 fillStruct pc=00400041 sp=00004fe0 base=00004fe0", "Storage: Stack[0x4]:4", RowKey.TYPE, "Type: MyStruct *", RowKey.LOCATION,
RowKey.STORAGE, "Storage: Stack[0x4]:4", "Location: 00004fe4:4",
RowKey.TYPE, "Type: MyStruct *",
RowKey.LOCATION, "Location: 00004fe4:4",
// NOTE: Value is the pointer, not the struct // NOTE: Value is the pointer, not the struct
RowKey.BYTES, "Bytes: (KNOWN) 00 00 60 00", RowKey.BYTES, "Bytes: (KNOWN) 00 00 60 00", RowKey.INTEGER,
RowKey.INTEGER, "Integer: (KNOWN) 6291456, 0x600000", "Integer: (KNOWN) 6291456, 0x600000", RowKey.VALUE, "Value: (KNOWN) 00600000",
RowKey.VALUE, "Value: (KNOWN) 00600000",
RowKey.WARNINGS, "IGNORED"), table); RowKey.WARNINGS, "IGNORED"), table);
} }
@ -1693,14 +1603,10 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest {
VariableValueTable table = getVariableValueTable(valuesService, loc.pLoc, VariableValueTable table = getVariableValueTable(valuesService, loc.pLoc,
traceManager.getCurrent(), loc.fLoc, loc.field); traceManager.getCurrent(), loc.fLoc, loc.field);
assertTable(Map.of( assertTable(Map.of(RowKey.NAME, "Name: y", RowKey.FRAME,
RowKey.NAME, "Name: y", "Frame: 0 fillStruct pc=00400041 sp=00004fe0 base=00004fe0", RowKey.TYPE, "Type: word",
RowKey.FRAME, "Frame: 0 fillStruct pc=00400041 sp=00004fe0 base=00004fe0", RowKey.LOCATION, "Location: 00600000:2", RowKey.BYTES, "Bytes: (KNOWN) e6 07",
RowKey.TYPE, "Type: word", RowKey.INTEGER, "Integer: (KNOWN) 2022, 0x7e6", RowKey.VALUE, "Value: (KNOWN) 7E6h",
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); RowKey.WARNINGS, "IGNORED"), table);
} }
@ -1718,14 +1624,10 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest {
VariableValueTable table = getVariableValueTable(valuesService, loc.pLoc, VariableValueTable table = getVariableValueTable(valuesService, loc.pLoc,
traceManager.getCurrent(), loc.fLoc, loc.field); traceManager.getCurrent(), loc.fLoc, loc.field);
assertTable(Map.of( assertTable(Map.of(RowKey.NAME, "Name: m", RowKey.FRAME,
RowKey.NAME, "Name: m", "Frame: 0 fillStruct pc=0040002e sp=00004fe0 base=00004fe0", RowKey.TYPE, "Type: byte",
RowKey.FRAME, "Frame: 0 fillStruct pc=0040002e sp=00004fe0 base=00004fe0", RowKey.LOCATION, "Location: 0060000a:1", RowKey.BYTES, "Bytes: (KNOWN) 0c",
RowKey.TYPE, "Type: byte", RowKey.INTEGER, "Integer: (KNOWN) 12, 0xc", RowKey.VALUE, "Value: (KNOWN) Ch",
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); RowKey.WARNINGS, "IGNORED"), table);
} }

View file

@ -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<T extends UndoableDomainObject>
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);
}
}

View file

@ -23,7 +23,6 @@ import ghidra.app.cmd.module.CreateDefaultTreeCmd;
import ghidra.app.plugin.PluginCategoryNames; import ghidra.app.plugin.PluginCategoryNames;
import ghidra.app.plugin.ProgramPlugin; import ghidra.app.plugin.ProgramPlugin;
import ghidra.framework.cmd.BackgroundCommand; import ghidra.framework.cmd.BackgroundCommand;
import ghidra.framework.model.DomainObject;
import ghidra.framework.plugintool.PluginInfo; import ghidra.framework.plugintool.PluginInfo;
import ghidra.framework.plugintool.PluginTool; import ghidra.framework.plugintool.PluginTool;
import ghidra.framework.plugintool.util.PluginStatus; import ghidra.framework.plugintool.util.PluginStatus;
@ -53,7 +52,6 @@ import ghidra.util.task.TaskMonitor;
) )
//@formatter:on //@formatter:on
public class SampleProgramTreePlugin extends ProgramPlugin { public class SampleProgramTreePlugin extends ProgramPlugin {
private Listing listing;
/** /**
* Construct a new SampleProgramTreePlugin. * Construct a new SampleProgramTreePlugin.
@ -90,8 +88,7 @@ public class SampleProgramTreePlugin extends ProgramPlugin {
* Method Modularize. * Method Modularize.
*/ */
private void modularize() { private void modularize() {
BackgroundCommand cmd = new ModularizeCommand(); ModularizeCommand cmd = new ModularizeCommand();
tool.executeBackgroundCommand(cmd, currentProgram); tool.executeBackgroundCommand(cmd, currentProgram);
} }
@ -99,7 +96,7 @@ public class SampleProgramTreePlugin extends ProgramPlugin {
* Background command that will create the new tree and organize it. * Background command that will create the new tree and organize it.
* *
*/ */
class ModularizeCommand extends BackgroundCommand { static class ModularizeCommand extends BackgroundCommand<Program> {
private int fragment_count = 0; private int fragment_count = 0;
private String programTreeName = "Sample Tree"; private String programTreeName = "Sample Tree";
@ -108,10 +105,9 @@ public class SampleProgramTreePlugin extends ProgramPlugin {
} }
@Override @Override
public boolean applyTo(DomainObject obj, TaskMonitor monitor) { public boolean applyTo(Program program, TaskMonitor monitor) {
Program program = (Program) obj;
listing = program.getListing(); Listing listing = program.getListing();
createDefaultTreeView(program, programTreeName); createDefaultTreeView(program, programTreeName);
@ -145,8 +141,8 @@ public class SampleProgramTreePlugin extends ProgramPlugin {
monitor.setMessage("Module " + start + " : " + mod_name); monitor.setMessage("Module " + start + " : " + mod_name);
ProgramModule mod = make_module(mod_name, frags); ProgramModule mod = make_module(listing, mod_name, frags);
makeFragment(start, end, "frag_" + fragment_count, mod); makeFragment(listing, start, end, "frag_" + fragment_count, mod);
fragment_count++; fragment_count++;
} }
@ -156,24 +152,17 @@ public class SampleProgramTreePlugin extends ProgramPlugin {
private void createDefaultTreeView(Program program, String defaultTreeName) { private void createDefaultTreeView(Program program, String defaultTreeName) {
String treeName = defaultTreeName; String treeName = defaultTreeName;
int oneUp = 1; int oneUp = 1;
Listing listing = program.getListing();
while (listing.getRootModule(treeName) != null) { while (listing.getRootModule(treeName) != null) {
treeName = defaultTreeName + "_" + oneUp; treeName = defaultTreeName + "_" + oneUp;
oneUp++; oneUp++;
} }
CreateDefaultTreeCmd cmd = new CreateDefaultTreeCmd(defaultTreeName); CreateDefaultTreeCmd cmd = new CreateDefaultTreeCmd(defaultTreeName);
if (tool.execute(cmd, program)) { cmd.applyTo(program);
tool.setStatusInfo(cmd.getStatusMsg());
}
} }
/** private ProgramModule make_module(Listing listing, String moduleName,
* Method make_module. ProgramModule parent) {
* @param start
* @param entry_address
* @param prev_name
* @param code
*/
private ProgramModule make_module(String moduleName, ProgramModule parent) {
String modName = moduleName; String modName = moduleName;
int oneUp = 1; int oneUp = 1;
@ -183,6 +172,7 @@ public class SampleProgramTreePlugin extends ProgramPlugin {
newMod = parent.createModule(modName); newMod = parent.createModule(modName);
} }
catch (DuplicateNameException e) { catch (DuplicateNameException e) {
// ignore
} }
modName = moduleName + "_" + oneUp; modName = moduleName + "_" + oneUp;
oneUp++; oneUp++;
@ -190,19 +180,14 @@ public class SampleProgramTreePlugin extends ProgramPlugin {
return newMod; return newMod;
} }
/** private ProgramFragment makeFragment(Listing listing, Address start, Address end,
* Method make_frag. String fragmentName, ProgramModule parent) {
* @param start
* @param entry_address
* @param prev_name
*/
private ProgramFragment makeFragment(Address start, Address end, String fragmentName,
ProgramModule parent) {
try { try {
parent.createFragment(fragmentName); parent.createFragment(fragmentName);
} }
catch (DuplicateNameException e) { catch (DuplicateNameException e) {
// ignore
} }
ProgramFragment frag = listing.getFragment(programTreeName, fragmentName); ProgramFragment frag = listing.getFragment(programTreeName, fragmentName);

View file

@ -15,10 +15,12 @@
*/ */
package ghidra.app.cmd.analysis; package ghidra.app.cmd.analysis;
import java.util.ArrayList;
import java.util.List;
import ghidra.app.cmd.disassemble.SetFlowOverrideCmd; import ghidra.app.cmd.disassemble.SetFlowOverrideCmd;
import ghidra.app.plugin.core.analysis.AutoAnalysisManager; import ghidra.app.plugin.core.analysis.AutoAnalysisManager;
import ghidra.framework.cmd.BackgroundCommand; import ghidra.framework.cmd.BackgroundCommand;
import ghidra.framework.model.DomainObject;
import ghidra.program.model.address.*; import ghidra.program.model.address.*;
import ghidra.program.model.listing.*; import ghidra.program.model.listing.*;
import ghidra.program.model.symbol.*; import ghidra.program.model.symbol.*;
@ -26,14 +28,11 @@ import ghidra.util.exception.AssertException;
import ghidra.util.exception.CancelledException; import ghidra.util.exception.CancelledException;
import ghidra.util.task.TaskMonitor; import ghidra.util.task.TaskMonitor;
import java.util.ArrayList;
import java.util.List;
/** /**
* Identifies functions to which Jump references exist and converts * Identifies functions to which Jump references exist and converts
* the associated branching instruction flow to a CALL-RETURN * the associated branching instruction flow to a CALL-RETURN
*/ */
public class SharedReturnAnalysisCmd extends BackgroundCommand { public class SharedReturnAnalysisCmd extends BackgroundCommand<Program> {
private AddressSetView set; private AddressSetView set;
private boolean assumeContiguousFunctions = false; private boolean assumeContiguousFunctions = false;
@ -58,9 +57,7 @@ public class SharedReturnAnalysisCmd extends BackgroundCommand {
} }
@Override @Override
public boolean applyTo(DomainObject obj, TaskMonitor monitor) { public boolean applyTo(Program program, TaskMonitor monitor) {
Program program = (Program) obj;
try { try {
@ -180,8 +177,8 @@ public class SharedReturnAnalysisCmd extends BackgroundCommand {
} }
// if we have not passed lastFunctionAfter then no change to lastFunctionBefore // if we have not passed lastFunctionAfter then no change to lastFunctionBefore
if (functionBeforeSrc != null && if (functionBeforeSrc != null && (functionAfterSrc == Address.NO_ADDRESS ||
(functionAfterSrc == Address.NO_ADDRESS || srcAddr.compareTo(functionAfterSrc) < 0)) { srcAddr.compareTo(functionAfterSrc) < 0)) {
// we have not passed lastFunctionAfterSrc - no change to lastFunctionBeforeSrc // we have not passed lastFunctionAfterSrc - no change to lastFunctionBeforeSrc
} }
else { else {
@ -342,39 +339,39 @@ public class SharedReturnAnalysisCmd extends BackgroundCommand {
} }
private void checkAllJumpReferences(Program program, TaskMonitor monitor) // private void checkAllJumpReferences(Program program, TaskMonitor monitor)
throws CancelledException { // throws CancelledException {
//
SymbolTable symbolTable = program.getSymbolTable(); // SymbolTable symbolTable = program.getSymbolTable();
//
InstructionIterator instructionIter = program.getListing().getInstructions(set, true); // InstructionIterator instructionIter = program.getListing().getInstructions(set, true);
while (instructionIter.hasNext()) { // while (instructionIter.hasNext()) {
monitor.checkCancelled(); // monitor.checkCancelled();
Instruction instr = instructionIter.next(); // Instruction instr = instructionIter.next();
FlowType ft = instr.getFlowType(); // FlowType ft = instr.getFlowType();
if (!ft.isJump()) { // if (!ft.isJump()) {
continue; // continue;
} // }
Reference ref = getSingleFlowReferenceFrom(instr); // Reference ref = getSingleFlowReferenceFrom(instr);
if (ref == null) { // if (ref == null) {
continue; // continue;
} // }
// if there is a function at this address, this is a thunk // // if there is a function at this address, this is a thunk
// Handle differently // // Handle differently
if (program.getFunctionManager().getFunctionAt(instr.getMinAddress()) != null) { // if (program.getFunctionManager().getFunctionAt(instr.getMinAddress()) != null) {
continue; // continue;
} // }
Symbol s = symbolTable.getPrimarySymbol(ref.getToAddress()); // Symbol s = symbolTable.getPrimarySymbol(ref.getToAddress());
if (s != null && s.getSymbolType() == SymbolType.FUNCTION) { // if (s != null && s.getSymbolType() == SymbolType.FUNCTION) {
if (instr.getFlowOverride() != FlowOverride.NONE) { // if (instr.getFlowOverride() != FlowOverride.NONE) {
continue; // continue;
} // }
SetFlowOverrideCmd cmd = // SetFlowOverrideCmd cmd =
new SetFlowOverrideCmd(instr.getMinAddress(), FlowOverride.CALL_RETURN); // new SetFlowOverrideCmd(instr.getMinAddress(), FlowOverride.CALL_RETURN);
cmd.applyTo(program); // cmd.applyTo(program);
} // }
} // }
} // }
private void processFunctionJumpReferences(Program program, Address entry, TaskMonitor monitor) private void processFunctionJumpReferences(Program program, Address entry, TaskMonitor monitor)
throws CancelledException { throws CancelledException {

View file

@ -16,14 +16,13 @@
package ghidra.app.cmd.comments; package ghidra.app.cmd.comments;
import ghidra.framework.cmd.Command; import ghidra.framework.cmd.Command;
import ghidra.framework.model.DomainObject;
import ghidra.program.model.address.Address; import ghidra.program.model.address.Address;
import ghidra.program.model.listing.*; import ghidra.program.model.listing.*;
/** /**
* Command to append a specific type of comment on a code unit. * Command to append a specific type of comment on a code unit.
*/ */
public class AppendCommentCmd implements Command { public class AppendCommentCmd implements Command<Program> {
private Address address; private Address address;
private int commentType; private int commentType;
@ -49,23 +48,16 @@ public class AppendCommentCmd implements Command {
cmdName = "Append Comment"; cmdName = "Append Comment";
} }
/**
* @see ghidra.framework.cmd.Command#getName()
*/
@Override @Override
public String getName() { public String getName() {
return cmdName; return cmdName;
} }
/**
* @see ghidra.framework.cmd.Command#applyTo(ghidra.framework.model.DomainObject)
*/
@Override @Override
public boolean applyTo(DomainObject obj) { public boolean applyTo(Program program) {
CodeUnit cu = getCodeUnit((Program) obj); CodeUnit cu = getCodeUnit(program);
if (cu == null) { if (cu == null) {
message = message = "No Instruction or Data found for address " + address.toString() +
"No Instruction or Data found for address " + address.toString() +
" Is this address valid?"; " Is this address valid?";
return false; return false;
} }
@ -95,9 +87,6 @@ public class AppendCommentCmd implements Command {
return cu; return cu;
} }
/**
* @see ghidra.framework.cmd.Command#getStatusMsg()
*/
@Override @Override
public String getStatusMsg() { public String getStatusMsg() {
return message; return message;

View file

@ -20,7 +20,6 @@ import java.util.List;
import ghidra.app.util.CodeUnitInfo; import ghidra.app.util.CodeUnitInfo;
import ghidra.framework.cmd.Command; import ghidra.framework.cmd.Command;
import ghidra.framework.model.DomainObject;
import ghidra.program.model.address.Address; import ghidra.program.model.address.Address;
import ghidra.program.model.listing.*; import ghidra.program.model.listing.*;
import ghidra.program.model.pcode.Varnode; 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. * Undoable edit for pasting code unit information at a location.
* This class actually does the work of the "paste." * This class actually does the work of the "paste."
*/ */
public class CodeUnitInfoPasteCmd implements Command { public class CodeUnitInfoPasteCmd implements Command<Program> {
// TODO: should refactor to handle all variables in a consistent fashion // 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. * Creates a new command for pasting comments/labels.
* @param startAddr starting address for info * @param startAddr starting address for info
* @param infoList list of CodeUnitInfo objects that will be applied * @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<CodeUnitInfo> infoList, boolean pasteLabels, public CodeUnitInfoPasteCmd(Address startAddr, List<CodeUnitInfo> infoList, boolean pasteLabels,
boolean pasteComments) { boolean pasteComments) {
@ -65,19 +66,14 @@ public class CodeUnitInfoPasteCmd implements Command {
return "Paste Labels/Comments"; return "Paste Labels/Comments";
} }
/* (non-Javadoc)
* @see ghidra.framework.cmd.Command#applyTo(ghidra.framework.model.DomainObject)
*/
@Override @Override
public boolean applyTo(DomainObject obj) { public boolean applyTo(Program program) {
Program program = (Program) obj;
SymbolTable symTable = program.getSymbolTable(); SymbolTable symTable = program.getSymbolTable();
Listing listing = program.getListing(); Listing listing = program.getListing();
boolean offCutExists = false; boolean offCutExists = false;
for (int i = 0; i < infoList.size(); i++) { for (CodeUnitInfo info : infoList) {
CodeUnitInfo info = infoList.get(i);
Address a = startAddr.add(info.getIndex()); Address a = startAddr.add(info.getIndex());
CodeUnit cu = listing.getCodeUnitAt(a); CodeUnit cu = listing.getCodeUnitAt(a);
if (cu == null) { if (cu == null) {
@ -133,8 +129,8 @@ public class CodeUnitInfoPasteCmd implements Command {
function.setName(fnName, info.getPrimarySymbolSource()); function.setName(fnName, info.getPrimarySymbolSource());
} }
catch (DuplicateNameException e) { catch (DuplicateNameException e) {
messages.append("Could not set function name--duplicate name: " + fnName).append( messages.append("Could not set function name--duplicate name: " + fnName)
'\n'); .append('\n');
} }
catch (InvalidInputException e) { catch (InvalidInputException e) {
// shouldn't happen // shouldn't happen
@ -175,8 +171,8 @@ public class CodeUnitInfoPasteCmd implements Command {
} }
catch (DuplicateNameException e) { catch (DuplicateNameException e) {
messages.append( messages.append(
"Could not set stack variable name--duplicate name: " + fnName).append( "Could not set stack variable name--duplicate name: " + fnName)
'\n'); .append('\n');
} }
catch (InvalidInputException e) { catch (InvalidInputException e) {
// shouldn't happen // shouldn't happen
@ -204,8 +200,8 @@ public class CodeUnitInfoPasteCmd implements Command {
var.setName(varNames[i], varSources[i]); var.setName(varNames[i], varSources[i]);
} }
catch (DuplicateNameException e) { catch (DuplicateNameException e) {
messages.append( messages.append("Could not set variable name--duplicate name: " + fnName)
"Could not set variable name--duplicate name: " + fnName).append('\n'); .append('\n');
} }
catch (InvalidInputException e) { catch (InvalidInputException e) {
// shouldn't happen // shouldn't happen
@ -219,8 +215,7 @@ public class CodeUnitInfoPasteCmd implements Command {
} }
private Variable findStackVar(Variable[] stackVars, int stackOffset, int firstUseOffset) { private Variable findStackVar(Variable[] stackVars, int stackOffset, int firstUseOffset) {
for (int k = 0; k < stackVars.length; k++) { for (Variable var : stackVars) {
Variable var = stackVars[k];
if (stackOffset == var.getStackOffset() && firstUseOffset == var.getFirstUseOffset()) { if (stackOffset == var.getStackOffset() && firstUseOffset == var.getFirstUseOffset()) {
return var; return var;
} }
@ -229,8 +224,7 @@ public class CodeUnitInfoPasteCmd implements Command {
} }
private Variable findVar(Variable[] vars, Address storageAddr, int firstUseOffset) { private Variable findVar(Variable[] vars, Address storageAddr, int firstUseOffset) {
for (int k = 0; k < vars.length; k++) { for (Variable var : vars) {
Variable var = vars[k];
Varnode varnode = var.getVariableStorage().getFirstVarnode(); Varnode varnode = var.getVariableStorage().getFirstVarnode();
if (varnode != null && firstUseOffset == var.getFirstUseOffset() && if (varnode != null && firstUseOffset == var.getFirstUseOffset() &&
storageAddr.equals(varnode.getAddress())) { storageAddr.equals(varnode.getAddress())) {
@ -277,8 +271,8 @@ public class CodeUnitInfoPasteCmd implements Command {
} }
} }
catch (DuplicateNameException e) { catch (DuplicateNameException e) {
messages.append("Could not set label name--duplicate name: " + primaryName).append( messages.append("Could not set label name--duplicate name: " + primaryName)
'\n'); .append('\n');
} }
catch (InvalidInputException e) { catch (InvalidInputException e) {
// should not happen // should not happen
@ -359,12 +353,12 @@ public class CodeUnitInfoPasteCmd implements Command {
private String[] appendComment(String[] comment1, String[] comment2) { private String[] appendComment(String[] comment1, String[] comment2) {
// first check for duplicate comments // first check for duplicate comments
ArrayList<String> list = new ArrayList<String>(); ArrayList<String> list = new ArrayList<String>();
for (int i = 0; i < comment2.length; i++) { for (String element : comment2) {
list.add(comment2[i]); list.add(element);
} }
for (int i = 0; i < comment1.length; i++) { for (String element : comment1) {
for (int j = 0; j < list.size(); j++) { for (int j = 0; j < list.size(); j++) {
if (comment1[i].equals(list.get(j))) { if (element.equals(list.get(j))) {
list.remove(j); list.remove(j);
--j; --j;
} }

View file

@ -17,14 +17,13 @@ package ghidra.app.cmd.comments;
import ghidra.app.util.viewer.field.CommentUtils; import ghidra.app.util.viewer.field.CommentUtils;
import ghidra.framework.cmd.Command; import ghidra.framework.cmd.Command;
import ghidra.framework.model.DomainObject;
import ghidra.program.model.address.Address; import ghidra.program.model.address.Address;
import ghidra.program.model.listing.*; import ghidra.program.model.listing.*;
/** /**
* Command to set a specific type of comment on a code unit. * Command to set a specific type of comment on a code unit.
*/ */
public class SetCommentCmd implements Command { public class SetCommentCmd implements Command<Program> {
private Address address; private Address address;
private int commentType; private int commentType;
@ -67,8 +66,7 @@ public class SetCommentCmd implements Command {
} }
@Override @Override
public boolean applyTo(DomainObject obj) { public boolean applyTo(Program program) {
Program program = (Program) obj;
CodeUnit cu = getCodeUnit(program); CodeUnit cu = getCodeUnit(program);
if (cu == null) { if (cu == null) {
message = "No Instruction or Data found for address " + address.toString() + message = "No Instruction or Data found for address " + address.toString() +

View file

@ -17,14 +17,13 @@ package ghidra.app.cmd.comments;
import ghidra.app.util.viewer.field.CommentUtils; import ghidra.app.util.viewer.field.CommentUtils;
import ghidra.framework.cmd.Command; import ghidra.framework.cmd.Command;
import ghidra.framework.model.DomainObject;
import ghidra.program.model.address.Address; import ghidra.program.model.address.Address;
import ghidra.program.model.listing.*; import ghidra.program.model.listing.*;
/** /**
* Command for editing and removing comments at an address. * Command for editing and removing comments at an address.
*/ */
public class SetCommentsCmd implements Command { public class SetCommentsCmd implements Command<Program> {
private Address address; private Address address;
private String preComment; private String preComment;
@ -79,13 +78,8 @@ public class SetCommentsCmd implements Command {
return !oldValue.equals(newValue); return !oldValue.equals(newValue);
} }
/**
*
* @see ghidra.framework.cmd.Command#applyTo(ghidra.framework.model.DomainObject)
*/
@Override @Override
public boolean applyTo(DomainObject obj) { public boolean applyTo(Program program) {
Program program = (Program) obj;
CodeUnit cu = getCodeUnit(program); CodeUnit cu = getCodeUnit(program);
if (cu != null) { if (cu != null) {
@ -138,9 +132,6 @@ public class SetCommentsCmd implements Command {
return cu; return cu;
} }
/**
* @see ghidra.framework.cmd.Command#getStatusMsg()
*/
@Override @Override
public String getStatusMsg() { public String getStatusMsg() {
return msg; return msg;

View file

@ -16,8 +16,6 @@
package ghidra.app.cmd.data; package ghidra.app.cmd.data;
import ghidra.framework.cmd.Command; import ghidra.framework.cmd.Command;
import ghidra.framework.model.DomainObject;
import ghidra.program.model.address.Address; import ghidra.program.model.address.Address;
import ghidra.program.model.data.DataType; import ghidra.program.model.data.DataType;
import ghidra.program.model.data.Structure; import ghidra.program.model.data.Structure;
@ -26,13 +24,10 @@ import ghidra.program.model.listing.Program;
/** /**
* A base class to hold duplicate information for commands that create * A base class to hold duplicate information for commands that create
* structures. This class implements the logic of the * 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. * only to implement the abstract methods.
*
*
* @since Tracker Id 383
*/ */
public abstract class AbstractCreateStructureCmd implements Command { public abstract class AbstractCreateStructureCmd implements Command<Program> {
private String statusMessage; private String statusMessage;
private String structureName; private String structureName;
@ -41,7 +36,7 @@ public abstract class AbstractCreateStructureCmd implements Command {
/** /**
* Initializes the this class to create a structure with the given name * Initializes the this class to create a structure with the given name
* and address when the {@link #applyTo(DomainObject)} is called. * and address when the {@link #applyTo(Program)} is called.
* *
* @param name The name of the structure to create. * @param name The name of the structure to create.
* @param address The address of the structure. * @param address The address of the structure.
@ -51,23 +46,13 @@ public abstract class AbstractCreateStructureCmd implements Command {
structureName = name; structureName = name;
} }
/** @Override
* Applies this command to the given domain object. public boolean applyTo(Program program) {
* <p>
* 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 { try {
Program program = (Program) domainObject;
Structure structure = createStructure(structureAddress, program); Structure structure = createStructure(structureAddress, program);
setNewDataType(initializeStructureData(program, structure)); setNewDataType(initializeStructureData(program, structure));
} catch (IllegalArgumentException iae) { }
catch (IllegalArgumentException iae) {
setStatusMsg(iae.getMessage()); setStatusMsg(iae.getMessage());
return false; return false;
} }
@ -86,8 +71,7 @@ public abstract class AbstractCreateStructureCmd implements Command {
* @throws IllegalArgumentException If the data at the given address is * @throws IllegalArgumentException If the data at the given address is
* not valid for creating a structure. * not valid for creating a structure.
*/ */
/*package*/ abstract Structure createStructure( Address address, /*package*/ abstract Structure createStructure(Address address, Program program)
Program program )
throws IllegalArgumentException; throws IllegalArgumentException;
/** /**
@ -96,12 +80,12 @@ public abstract class AbstractCreateStructureCmd implements Command {
* structure with data and then returning the data type object that * structure with data and then returning the data type object that
* represents the newly created structure. * represents the newly created structure.
* *
* @param structureInfo The structure info object that describes the newly * @param program program to be modified
* @param structure The structure definition that describes the newly
* created structure. * created structure.
* @return The new data type that represents the created structure. * @return The new data type that represents the created structure.
*/ */
/*package*/ abstract DataType initializeStructureData( /*package*/ abstract DataType initializeStructureData(Program program, Structure structure);
Program program, Structure structure );
/** /**
* Sets the new data type of this command. * Sets the new data type of this command.
@ -133,9 +117,7 @@ public abstract class AbstractCreateStructureCmd implements Command {
statusMessage = message; statusMessage = message;
} }
/** @Override
* @see ghidra.framework.cmd.Command#getStatusMsg()
*/
public String getStatusMsg() { public String getStatusMsg() {
return statusMessage; return statusMessage;
} }
@ -144,9 +126,7 @@ public abstract class AbstractCreateStructureCmd implements Command {
return structureName; return structureName;
} }
/** @Override
* @see ghidra.framework.cmd.Command#getName()
*/
public String getName() { public String getName() {
return "Create Structure"; return "Create Structure";
} }

View file

@ -16,7 +16,6 @@
package ghidra.app.cmd.data; package ghidra.app.cmd.data;
import ghidra.framework.cmd.Command; import ghidra.framework.cmd.Command;
import ghidra.framework.model.DomainObject;
import ghidra.program.model.address.*; import ghidra.program.model.address.*;
import ghidra.program.model.data.*; import ghidra.program.model.data.*;
import ghidra.program.model.listing.*; import ghidra.program.model.listing.*;
@ -27,7 +26,7 @@ import ghidra.util.Msg;
* Command to create an array. All conflicting data will be cleared. * Command to create an array. All conflicting data will be cleared.
* *
*/ */
public class CreateArrayCmd implements Command { public class CreateArrayCmd implements Command<Program> {
private String msg; private String msg;
private Address addr; private Address addr;
private int numElements; private int numElements;
@ -51,8 +50,7 @@ public class CreateArrayCmd implements Command {
} }
@Override @Override
public boolean applyTo(DomainObject obj) { public boolean applyTo(Program program) {
Program program = (Program)obj;
Listing listing = program.getListing(); Listing listing = program.getListing();
try { try {
ArrayDataType adt = new ArrayDataType(dataType, numElements, elementLength, ArrayDataType adt = new ArrayDataType(dataType, numElements, elementLength,
@ -68,7 +66,8 @@ public class CreateArrayCmd implements Command {
} }
listing.clearCodeUnits(addr, endAddr, false); listing.clearCodeUnits(addr, endAddr, false);
listing.createData(addr, adt, adt.getLength()); listing.createData(addr, adt, adt.getLength());
} catch (AddressOverflowException e1) { }
catch (AddressOverflowException e1) {
msg = "Can't create data because length exceeds address space"; msg = "Can't create data because length exceeds address space";
return false; return false;
} }

View file

@ -16,7 +16,6 @@
package ghidra.app.cmd.data; package ghidra.app.cmd.data;
import ghidra.framework.cmd.Command; import ghidra.framework.cmd.Command;
import ghidra.framework.model.DomainObject;
import ghidra.program.model.address.Address; import ghidra.program.model.address.Address;
import ghidra.program.model.data.*; import ghidra.program.model.data.*;
import ghidra.program.model.listing.*; import ghidra.program.model.listing.*;
@ -27,7 +26,7 @@ import ghidra.util.Msg;
* within the targeted structure will be replaced with the new array component. * within the targeted structure will be replaced with the new array component.
* *
*/ */
public class CreateArrayInStructureCmd implements Command { public class CreateArrayInStructureCmd implements Command<Program> {
private String msg; private String msg;
private Address addr; private Address addr;
private int numElements; private int numElements;
@ -50,8 +49,7 @@ public class CreateArrayInStructureCmd implements Command {
* the array should be created. The component path is an array of integers where each integer * 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. * is a component index of the component above it.
*/ */
public CreateArrayInStructureCmd(Address addr, int numElements, DataType dt, public CreateArrayInStructureCmd(Address addr, int numElements, DataType dt, int[] compPath) {
int[] compPath) {
this.addr = addr; this.addr = addr;
this.numElements = numElements; this.numElements = numElements;
this.dataType = dt; this.dataType = dt;
@ -59,8 +57,7 @@ public class CreateArrayInStructureCmd implements Command {
} }
@Override @Override
public boolean applyTo(DomainObject obj) { public boolean applyTo(Program program) {
Program program = (Program)obj;
Listing listing = program.getListing(); Listing listing = program.getListing();
Data data = listing.getDataContaining(addr); Data data = listing.getDataContaining(addr);

View file

@ -16,7 +16,6 @@
package ghidra.app.cmd.data; package ghidra.app.cmd.data;
import ghidra.framework.cmd.BackgroundCommand; import ghidra.framework.cmd.BackgroundCommand;
import ghidra.framework.model.DomainObject;
import ghidra.program.model.address.*; import ghidra.program.model.address.*;
import ghidra.program.model.data.DataType; import ghidra.program.model.data.DataType;
import ghidra.program.model.data.DataUtilities; 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 * of a pointer, then a pointer to dataType will only be created if there are
* enough undefined bytes following to make a pointer. * enough undefined bytes following to make a pointer.
*/ */
public class CreateDataBackgroundCmd extends BackgroundCommand { public class CreateDataBackgroundCmd extends BackgroundCommand<Program> {
private static final int EVENT_LIMIT = 1000;
private AddressSetView addrSet; private AddressSetView addrSet;
private DataType newDataType; private DataType newDataType;
@ -76,12 +74,7 @@ public class CreateDataBackgroundCmd extends BackgroundCommand {
} }
@Override @Override
public boolean applyTo(DomainObject obj, TaskMonitor monitor) { public boolean applyTo(Program program, TaskMonitor monitor) {
return doApplyTo(obj, monitor);
}
public boolean doApplyTo(DomainObject obj, TaskMonitor monitor) {
Program program = (Program) obj;
Listing listing = program.getListing(); Listing listing = program.getListing();
InstructionIterator iter = listing.getInstructions(addrSet, true); InstructionIterator iter = listing.getInstructions(addrSet, true);
if (iter.hasNext()) { if (iter.hasNext()) {

View file

@ -16,7 +16,6 @@
package ghidra.app.cmd.data; package ghidra.app.cmd.data;
import ghidra.framework.cmd.Command; import ghidra.framework.cmd.Command;
import ghidra.framework.model.DomainObject;
import ghidra.program.model.address.Address; import ghidra.program.model.address.Address;
import ghidra.program.model.data.DataType; import ghidra.program.model.data.DataType;
import ghidra.program.model.data.DataUtilities; 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) * @see DataUtilities#createData(Program, Address, DataType, int, boolean, DataUtilities.ClearDataMode)
*/ */
public class CreateDataCmd implements Command { public class CreateDataCmd implements Command<Program> {
private Address addr; private Address addr;
private DataType newDataType; private DataType newDataType;
@ -119,10 +118,9 @@ public class CreateDataCmd implements Command {
} }
@Override @Override
public boolean applyTo(DomainObject obj) { public boolean applyTo(Program program) {
try { try {
DataUtilities.createData((Program) obj, addr, newDataType, -1, stackPointers, DataUtilities.createData(program, addr, newDataType, -1, stackPointers, clearMode);
clearMode);
return true; return true;
} }
catch (Exception e) { catch (Exception e) {

View file

@ -16,7 +16,6 @@
package ghidra.app.cmd.data; package ghidra.app.cmd.data;
import ghidra.framework.cmd.BackgroundCommand; import ghidra.framework.cmd.BackgroundCommand;
import ghidra.framework.model.DomainObject;
import ghidra.program.model.address.Address; import ghidra.program.model.address.Address;
import ghidra.program.model.data.*; import ghidra.program.model.data.*;
import ghidra.program.model.listing.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. * Background command to create data across a selection inside of a structure.
* *
*/ */
public class CreateDataInStructureBackgroundCmd extends BackgroundCommand { public class CreateDataInStructureBackgroundCmd extends BackgroundCommand<Program> {
// TODO: Not sure any of this will work for a packed structure which does not support // TODO: Not sure any of this will work for a packed structure which does not support
// offset-based component manipulation (see GP-3740) // 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) * @see ghidra.framework.cmd.BackgroundCommand#applyTo(ghidra.framework.model.DomainObject, ghidra.util.task.TaskMonitor)
*/ */
@Override @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 data = program.getListing().getDefinedDataContaining(addr);
Data startData = data.getComponent(startPath); Data startData = data.getComponent(startPath);
if (startData == null) { if (startData == null) {

View file

@ -16,7 +16,6 @@
package ghidra.app.cmd.data; package ghidra.app.cmd.data;
import ghidra.framework.cmd.Command; import ghidra.framework.cmd.Command;
import ghidra.framework.model.DomainObject;
import ghidra.program.model.address.Address; import ghidra.program.model.address.Address;
import ghidra.program.model.data.*; import ghidra.program.model.data.*;
import ghidra.program.model.listing.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. * Command to Create data inside of a structure.
*/ */
public class CreateDataInStructureCmd implements Command { public class CreateDataInStructureCmd implements Command<Program> {
// TODO: Not sure any of this will work for a packed structure which does not support // TODO: Not sure any of this will work for a packed structure which does not support
// offset-based component manipulation (see GP-3740) // offset-based component manipulation (see GP-3740)
@ -69,12 +68,8 @@ public class CreateDataInStructureCmd implements Command {
this.stackPointers = stackPointers; this.stackPointers = stackPointers;
} }
/**
* @see ghidra.framework.cmd.Command#applyTo(ghidra.framework.model.DomainObject)
*/
@Override @Override
public boolean applyTo(DomainObject obj) { public boolean applyTo(Program program) {
Program program = (Program) obj;
Data data = program.getListing().getDefinedDataContaining(addr); Data data = program.getListing().getDefinedDataContaining(addr);
Data dataComp = data.getComponent(componentPath); Data dataComp = data.getComponent(componentPath);
if (dataComp == null) { if (dataComp == null) {
@ -142,17 +137,11 @@ public class CreateDataInStructureCmd implements Command {
return true; return true;
} }
/**
* @see ghidra.framework.cmd.Command#getStatusMsg()
*/
@Override @Override
public String getStatusMsg() { public String getStatusMsg() {
return msg; return msg;
} }
/**
* @see ghidra.framework.cmd.Command#getName()
*/
@Override @Override
public String getName() { public String getName() {
return "Create " + newDataType.getDisplayName() + " component"; return "Create " + newDataType.getDisplayName() + " component";

View file

@ -16,7 +16,6 @@
package ghidra.app.cmd.data; package ghidra.app.cmd.data;
import ghidra.framework.cmd.Command; import ghidra.framework.cmd.Command;
import ghidra.framework.model.DomainObject;
import ghidra.program.model.address.Address; import ghidra.program.model.address.Address;
import ghidra.program.model.data.*; import ghidra.program.model.data.*;
import ghidra.program.model.data.DataUtilities.ClearDataMode; 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. * Command to create a String and optionally label it.
* *
*/ */
public class CreateStringCmd implements Command { public class CreateStringCmd implements Command<Program> {
private final Address addr; private final Address addr;
private final AbstractStringDataType stringDataType; private final AbstractStringDataType stringDataType;
private int length = -1; private int length = -1;
@ -39,6 +38,14 @@ public class CreateStringCmd implements Command {
: (length > 0) ? new StringDataType() : new TerminatedStringDataType(); : (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, public CreateStringCmd(Address addr, AbstractStringDataType stringDataType, int length,
ClearDataMode clearMode) { ClearDataMode clearMode) {
this.addr = addr; 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) { public CreateStringCmd(Address addr, int length, boolean unicode, ClearDataMode clearMode) {
this(addr, getStringDataType(unicode, length), length, 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) { public CreateStringCmd(Address addr, int length, boolean unicode) {
this(addr, getStringDataType(unicode, length), length, ClearDataMode.CLEAR_SINGLE_DATA); 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) { public CreateStringCmd(Address addr) {
this(addr, -1, false); 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) { public CreateStringCmd(Address addr, int length) {
this(addr, length, false); this(addr, length, false);
} }
/**
*
* @see ghidra.framework.cmd.Command#applyTo(ghidra.framework.model.DomainObject)
*/
@Override @Override
public boolean applyTo(DomainObject obj) { public boolean applyTo(Program program) {
Program program = (Program) obj;
try { try {
DataUtilities.createData(program, addr, stringDataType, length, clearMode); DataUtilities.createData(program, addr, stringDataType, length, clearMode);
} }
@ -94,17 +109,11 @@ public class CreateStringCmd implements Command {
return true; return true;
} }
/**
* @see ghidra.framework.cmd.Command#getStatusMsg()
*/
@Override @Override
public String getStatusMsg() { public String getStatusMsg() {
return msg; return msg;
} }
/**
* @see ghidra.framework.cmd.Command#getName()
*/
@Override @Override
public String getName() { public String getName() {
return "Create String"; return "Create String";

View file

@ -1,6 +1,5 @@
/* ### /* ###
* IP: GHIDRA * IP: GHIDRA
* REVIEWED: YES
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -16,7 +15,9 @@
*/ */
package ghidra.app.cmd.data; 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.address.*;
import ghidra.program.model.data.*; import ghidra.program.model.data.*;
import ghidra.program.model.listing.*; import ghidra.program.model.listing.*;
@ -24,8 +25,6 @@ import ghidra.program.model.symbol.Reference;
import ghidra.program.model.symbol.ReferenceManager; import ghidra.program.model.symbol.ReferenceManager;
import ghidra.program.model.util.CodeUnitInsertionException; import ghidra.program.model.util.CodeUnitInsertionException;
import java.util.ArrayList;
/** /**
* Command to create a structure. * Command to create a structure.
*/ */
@ -62,10 +61,10 @@ public class CreateStructureCmd extends AbstractCreateStructureCmd{
/** /**
* Creates a new structure by using the provided structure and attaching * Creates a new structure by using the provided structure and attaching
* it to the program passed in the {@link #applyTo(DomainObject)} method. * it to the program passed in the {@link #applyTo(Program)} method.
* *
* @param newStructure The new structure to attach to the program * @param newStructure The new structure to attach to the program
* provided in the {@link #applyTo(DomainObject)} method. * provided in the {@link #applyTo(Program)} method.
* @param address the address at which to create the new structure. * @param address the address at which to create the new structure.
*/ */
public CreateStructureCmd(Structure newStructure, Address address) { public CreateStructureCmd(Structure newStructure, Address address) {
@ -78,12 +77,10 @@ public class CreateStructureCmd extends AbstractCreateStructureCmd{
* @see AbstractCreateStructureCmd#createStructure(Address, Program) * @see AbstractCreateStructureCmd#createStructure(Address, Program)
*/ */
@Override @Override
Structure createStructure( Address address, Structure createStructure(Address address, Program program) {
Program program ){
if (structure == null) { if (structure == null) {
structure = structure = StructureFactory.createStructureDataType(program, address,
StructureFactory.createStructureDataType( program, address,
structureDataLength, getStructureName(), true); structureDataLength, getStructureName(), true);
} }
@ -101,47 +98,47 @@ public class CreateStructureCmd extends AbstractCreateStructureCmd{
Address endAddress; Address endAddress;
try { try {
endAddress = getStructureAddress().addNoWrap(structureDataLength - 1); endAddress = getStructureAddress().addNoWrap(structureDataLength - 1);
} catch (AddressOverflowException e1){ }
catch (AddressOverflowException e1) {
throw new IllegalArgumentException( throw new IllegalArgumentException(
"Can't create structure because length exceeds address " + "Can't create structure because length exceeds address " + "space" +
"space" + structureDataLength ); structureDataLength);
} }
ReferenceManager refMgr = program.getReferenceManager(); ReferenceManager refMgr = program.getReferenceManager();
Reference[] refs = findExistingRefs( refMgr, program.getAddressFactory(), getStructureAddress(), Reference[] refs = findExistingRefs(refMgr, program.getAddressFactory(),
endAddress ); getStructureAddress(), endAddress);
listing.clearCodeUnits(getStructureAddress(), endAddress, false); listing.clearCodeUnits(getStructureAddress(), endAddress, false);
Data data = null; Data data = null;
try { try {
listing.createData(getStructureAddress(), localStructure, listing.createData(getStructureAddress(), localStructure, localStructure.getLength());
localStructure.getLength());
refMgr.removeAllReferencesFrom(getStructureAddress(), endAddress); refMgr.removeAllReferencesFrom(getStructureAddress(), endAddress);
addRefs(program, refMgr, refs); addRefs(program, refMgr, refs);
data = listing.getDataAt(getStructureAddress()); data = listing.getDataAt(getStructureAddress());
} catch(CodeUnitInsertionException e){ }
catch (CodeUnitInsertionException e) {
throw new IllegalArgumentException(e.getMessage()); throw new IllegalArgumentException(e.getMessage());
} }
return data.getDataType(); return data.getDataType();
} }
private Reference[] findExistingRefs(ReferenceManager refMgr, AddressFactory af, Address start, Address end) { private Reference[] findExistingRefs(ReferenceManager refMgr, AddressFactory af, Address start,
Address end) {
ArrayList<Reference> list = new ArrayList<Reference>(); ArrayList<Reference> list = new ArrayList<Reference>();
AddressIterator it = refMgr.getReferenceSourceIterator(new AddressSet(start, end), true); AddressIterator it = refMgr.getReferenceSourceIterator(new AddressSet(start, end), true);
while (it.hasNext()) { while (it.hasNext()) {
Address addr = it.next(); Address addr = it.next();
Reference[] refs = refMgr.getReferencesFrom(addr); Reference[] refs = refMgr.getReferencesFrom(addr);
for(int i=0;i<refs.length;i++) { Collections.addAll(list, refs);
list.add(refs[i]);
}
} }
Reference[] refList = new Reference[list.size()]; Reference[] refList = new Reference[list.size()];
return list.toArray(refList); return list.toArray(refList);
} }
private void addRefs(Program p, ReferenceManager refMgr, Reference[] refs) { private void addRefs(Program p, ReferenceManager refMgr, Reference[] refs) {
for(int i=0;i<refs.length;i++) { for (Reference ref : refs) {
refMgr.addReference(refs[i]); refMgr.addReference(ref);
} }
} }
} }

View file

@ -57,8 +57,8 @@ public class CreateStructureInStructureCmd extends AbstractCreateStructureCmd{
this.toPath = toPath; this.toPath = toPath;
} }
public CreateStructureInStructureCmd( Structure newStructure, public CreateStructureInStructureCmd(Structure newStructure, Address address, int[] fromPath,
Address address, int[] fromPath, int[] toPath ){ int[] toPath) {
this(address, fromPath, toPath); this(address, fromPath, toPath);
structure = newStructure; structure = newStructure;
} }
@ -67,12 +67,11 @@ public class CreateStructureInStructureCmd extends AbstractCreateStructureCmd{
* @see AbstractCreateStructureCmd#createStructure(Address, Program) * @see AbstractCreateStructureCmd#createStructure(Address, Program)
*/ */
/*package*/ @Override /*package*/ @Override
Structure createStructure( Address address, Structure createStructure(Address address, Program program) {
Program program ){
if (structure == null) { if (structure == null) {
structure = StructureFactory.createStructureDataTypeInStrucuture( structure = StructureFactory.createStructureDataTypeInStrucuture(program, address,
program, address, fromPath, toPath, getStructureName(), true ); fromPath, toPath, getStructureName(), true);
} }
return structure; return structure;
@ -84,25 +83,22 @@ public class CreateStructureInStructureCmd extends AbstractCreateStructureCmd{
/*package*/ @Override /*package*/ @Override
DataType initializeStructureData(Program program, Structure localStructure) { DataType initializeStructureData(Program program, Structure localStructure) {
Data data = program.getListing().getDataContaining( Data data = program.getListing().getDataContaining(getStructureAddress());
getStructureAddress() );
Data comp1 = data.getComponent(fromPath); Data comp1 = data.getComponent(fromPath);
Data comp2 = data.getComponent(toPath); Data comp2 = data.getComponent(toPath);
int dataLength = (comp2.getParentOffset() + comp2.getLength()) int dataLength = (comp2.getParentOffset() + comp2.getLength()) - comp1.getParentOffset();
- comp1.getParentOffset();
DataType parentDataType = comp1.getParent().getBaseDataType(); DataType parentDataType = comp1.getParent().getBaseDataType();
if (!(parentDataType instanceof Structure)) { if (!(parentDataType instanceof Structure)) {
throw new IllegalArgumentException( throw new IllegalArgumentException("Data not in a structure");
"Data not in a structure");
} }
Structure originalStructure = (Structure) parentDataType; Structure originalStructure = (Structure) parentDataType;
// clear and initialize the original structure and then get the new // clear and initialize the original structure and then get the new
// data // data
clearStruct(originalStructure, comp1.getParentOffset(), dataLength); clearStruct(originalStructure, comp1.getParentOffset(), dataLength);
originalStructure.replace(comp1.getComponentIndex(), originalStructure.replace(comp1.getComponentIndex(), localStructure,
localStructure, localStructure.getLength()); localStructure.getLength());
comp1 = data.getComponent(fromPath); comp1 = data.getComponent(fromPath);
return comp1.getDataType(); return comp1.getDataType();

View file

@ -1,6 +1,5 @@
/* ### /* ###
* IP: GHIDRA * IP: GHIDRA
* REVIEWED: YES
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -17,16 +16,15 @@
package ghidra.app.cmd.data; package ghidra.app.cmd.data;
import ghidra.framework.cmd.Command; import ghidra.framework.cmd.Command;
import ghidra.framework.model.DomainObject;
import ghidra.program.model.data.DataTypeComponent; import ghidra.program.model.data.DataTypeComponent;
import ghidra.program.model.listing.Program;
import ghidra.util.exception.DuplicateNameException; import ghidra.util.exception.DuplicateNameException;
/** /**
* Command to rename a component in a data type. * Command to rename a component in a data type.
* *
*/ */
public class RenameDataFieldCmd implements Command { public class RenameDataFieldCmd implements Command<Program> {
private DataTypeComponent comp; private DataTypeComponent comp;
private String newName; private String newName;
@ -43,11 +41,8 @@ public class RenameDataFieldCmd implements Command {
this.newName = newName; this.newName = newName;
} }
/* @Override
* (non-Javadoc) public boolean applyTo(Program program) {
* @see ghidra.framework.cmd.Command#applyTo(ghidra.framework.model.DomainObject)
*/
public boolean applyTo(DomainObject obj) {
if (comp == null) { if (comp == null) {
statusMsg = "Null data type"; statusMsg = "Null data type";
return false; return false;
@ -55,7 +50,8 @@ public class RenameDataFieldCmd implements Command {
try { try {
comp.setFieldName(newName); comp.setFieldName(newName);
return true; return true;
} catch(DuplicateNameException e) { }
catch (DuplicateNameException e) {
statusMsg = "Type name already exists: " + newName; statusMsg = "Type name already exists: " + newName;
} }
return false; return false;
@ -65,6 +61,7 @@ public class RenameDataFieldCmd implements Command {
* (non-Javadoc) * (non-Javadoc)
* @see ghidra.framework.cmd.Command#getStatusMsg() * @see ghidra.framework.cmd.Command#getStatusMsg()
*/ */
@Override
public String getStatusMsg() { public String getStatusMsg() {
return statusMsg; return statusMsg;
} }
@ -73,6 +70,7 @@ public class RenameDataFieldCmd implements Command {
* (non-Javadoc) * (non-Javadoc)
* @see ghidra.framework.cmd.Command#getName() * @see ghidra.framework.cmd.Command#getName()
*/ */
@Override
public String getName() { public String getName() {
return "Rename Data Field"; return "Rename Data Field";
} }

View file

@ -15,7 +15,8 @@
*/ */
package ghidra.app.cmd.disassemble; package ghidra.app.cmd.disassemble;
import ghidra.framework.model.DomainObject; import java.math.BigInteger;
import ghidra.program.disassemble.DisassemblerContextImpl; import ghidra.program.disassemble.DisassemblerContextImpl;
import ghidra.program.model.address.*; import ghidra.program.model.address.*;
import ghidra.program.model.lang.Register; import ghidra.program.model.lang.Register;
@ -24,8 +25,6 @@ import ghidra.program.model.listing.Program;
import ghidra.util.exception.CancelledException; import ghidra.util.exception.CancelledException;
import ghidra.util.task.TaskMonitor; import ghidra.util.task.TaskMonitor;
import java.math.BigInteger;
/** /**
* Command object for performing Arm/Thumb disassembly * Command object for performing Arm/Thumb disassembly
*/ */
@ -70,8 +69,7 @@ public class ArmDisassembleCommand extends DisassembleCommand {
} }
@Override @Override
synchronized public boolean applyTo(DomainObject obj, TaskMonitor monitor) { synchronized public boolean applyTo(Program program, TaskMonitor monitor) {
Program program = (Program) obj;
disassemblyPerformed = false; disassemblyPerformed = false;
unalignedStart = false; unalignedStart = false;

View file

@ -17,10 +17,10 @@ package ghidra.app.cmd.disassemble;
import ghidra.app.plugin.core.analysis.AutoAnalysisManager; import ghidra.app.plugin.core.analysis.AutoAnalysisManager;
import ghidra.framework.cmd.BackgroundCommand; import ghidra.framework.cmd.BackgroundCommand;
import ghidra.framework.model.DomainObject;
import ghidra.program.disassemble.*; import ghidra.program.disassemble.*;
import ghidra.program.model.address.*; 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.listing.*;
import ghidra.program.model.mem.Memory; import ghidra.program.model.mem.Memory;
import ghidra.program.model.mem.MemoryBlock; import ghidra.program.model.mem.MemoryBlock;
@ -30,7 +30,7 @@ import ghidra.util.task.TaskMonitor;
/** /**
* Command object for performing disassembly * Command object for performing disassembly
*/ */
public class DisassembleCommand extends BackgroundCommand { public class DisassembleCommand extends BackgroundCommand<Program> {
protected AddressSetView startSet; protected AddressSetView startSet;
protected boolean useDefaultRepeatPatternBehavior = false; 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 * @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. * 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 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, public DisassembleCommand(AddressSetView startSet, AddressSetView restrictedSet,
boolean followFlow) { boolean followFlow) {
@ -125,7 +127,7 @@ public class DisassembleCommand extends BackgroundCommand {
* Set code analysis enablement. By default new instructions will be submitted for * Set code analysis enablement. By default new instructions will be submitted for
* auto-analysis. * auto-analysis.
* *
* @param enable * @param enable true if incremental code analysis should be done, else false to prevent this.
*/ */
public void enableCodeAnalysis(boolean enable) { public void enableCodeAnalysis(boolean enable) {
this.enableAnalysis = enable; this.enableAnalysis = enable;
@ -150,8 +152,7 @@ public class DisassembleCommand extends BackgroundCommand {
} }
@Override @Override
synchronized public boolean applyTo(DomainObject obj, TaskMonitor monitor) { synchronized public boolean applyTo(Program program, TaskMonitor monitor) {
Program program = (Program) obj;
return doDisassembly(monitor, program, program.getLanguage().getInstructionAlignment()); return doDisassembly(monitor, program, program.getLanguage().getInstructionAlignment());
} }
@ -317,7 +318,7 @@ public class DisassembleCommand extends BackgroundCommand {
* *
* @param disassembler disassembler to use * @param disassembler disassembler to use
* @param seedSet set of addresses to be disassembled * @param seedSet set of addresses to be disassembled
* @param mgr * @param mgr auto analysis manager
* *
* @return addresses actually disassembled * @return addresses actually disassembled
*/ */

View file

@ -17,7 +17,6 @@ package ghidra.app.cmd.disassemble;
import java.math.BigInteger; import java.math.BigInteger;
import ghidra.framework.model.DomainObject;
import ghidra.program.disassemble.DisassemblerContextImpl; import ghidra.program.disassemble.DisassemblerContextImpl;
import ghidra.program.model.address.*; import ghidra.program.model.address.*;
import ghidra.program.model.lang.Register; import ghidra.program.model.lang.Register;
@ -70,8 +69,7 @@ public class Hcs12DisassembleCommand extends DisassembleCommand {
} }
@Override @Override
synchronized public boolean applyTo(DomainObject obj, TaskMonitor monitor) { synchronized public boolean applyTo(Program program, TaskMonitor monitor) {
Program program = (Program) obj;
disassemblyPerformed = false; disassemblyPerformed = false;
unalignedStart = false; unalignedStart = false;

View file

@ -17,7 +17,6 @@ package ghidra.app.cmd.disassemble;
import java.math.BigInteger; import java.math.BigInteger;
import ghidra.framework.model.DomainObject;
import ghidra.program.disassemble.DisassemblerContextImpl; import ghidra.program.disassemble.DisassemblerContextImpl;
import ghidra.program.model.address.*; import ghidra.program.model.address.*;
import ghidra.program.model.lang.Register; import ghidra.program.model.lang.Register;
@ -75,8 +74,7 @@ public class MipsDisassembleCommand extends DisassembleCommand {
} }
@Override @Override
synchronized public boolean applyTo(DomainObject obj, TaskMonitor monitor) { synchronized public boolean applyTo(Program program, TaskMonitor monitor) {
Program program = (Program) obj;
disassemblyPerformed = false; disassemblyPerformed = false;
unalignedStart = false; unalignedStart = false;
@ -90,7 +88,7 @@ public class MipsDisassembleCommand extends DisassembleCommand {
setStatusMsg("MIPS16 mode not supported"); setStatusMsg("MIPS16 mode not supported");
return false; return false;
} }
return super.applyTo(obj, monitor); return super.applyTo(program, monitor);
} }
RegisterValue m16modeValue = RegisterValue m16modeValue =

View file

@ -17,7 +17,6 @@ package ghidra.app.cmd.disassemble;
import java.math.BigInteger; import java.math.BigInteger;
import ghidra.framework.model.DomainObject;
import ghidra.program.disassemble.DisassemblerContextImpl; import ghidra.program.disassemble.DisassemblerContextImpl;
import ghidra.program.model.address.*; import ghidra.program.model.address.*;
import ghidra.program.model.lang.Register; import ghidra.program.model.lang.Register;
@ -77,8 +76,7 @@ public class PowerPCDisassembleCommand extends DisassembleCommand {
} }
@Override @Override
synchronized public boolean applyTo(DomainObject obj, TaskMonitor monitor) { synchronized public boolean applyTo(Program program, TaskMonitor monitor) {
Program program = (Program) obj;
disassemblyPerformed = false; disassemblyPerformed = false;
unalignedStart = false; unalignedStart = false;
@ -92,7 +90,7 @@ public class PowerPCDisassembleCommand extends DisassembleCommand {
setStatusMsg("PowerISA VLE mode not supported"); setStatusMsg("PowerISA VLE mode not supported");
return false; return false;
} }
return super.applyTo(obj, monitor); return super.applyTo(program, monitor);
} }
RegisterValue vlemodeValue = RegisterValue vlemodeValue =

View file

@ -16,14 +16,13 @@
package ghidra.app.cmd.disassemble; package ghidra.app.cmd.disassemble;
import ghidra.framework.cmd.BackgroundCommand; import ghidra.framework.cmd.BackgroundCommand;
import ghidra.framework.model.DomainObject;
import ghidra.program.disassemble.ReDisassembler; import ghidra.program.disassemble.ReDisassembler;
import ghidra.program.model.address.Address; import ghidra.program.model.address.Address;
import ghidra.program.model.listing.Program; import ghidra.program.model.listing.Program;
import ghidra.util.exception.CancelledException; import ghidra.util.exception.CancelledException;
import ghidra.util.task.TaskMonitor; import ghidra.util.task.TaskMonitor;
public class ReDisassembleCommand extends BackgroundCommand { public class ReDisassembleCommand extends BackgroundCommand<Program> {
private final Address seed; private final Address seed;
public ReDisassembleCommand(Address seed) { public ReDisassembleCommand(Address seed) {
@ -31,8 +30,8 @@ public class ReDisassembleCommand extends BackgroundCommand {
} }
@Override @Override
public boolean applyTo(DomainObject obj, TaskMonitor monitor) { public boolean applyTo(Program program, TaskMonitor monitor) {
ReDisassembler dis = new ReDisassembler((Program) obj); ReDisassembler dis = new ReDisassembler(program);
try { try {
dis.disasemble(seed, monitor); dis.disasemble(seed, monitor);
return true; return true;

View file

@ -1,6 +1,5 @@
/* ### /* ###
* IP: GHIDRA * IP: GHIDRA
* REVIEWED: YES
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -17,7 +16,6 @@
package ghidra.app.cmd.disassemble; package ghidra.app.cmd.disassemble;
import ghidra.framework.cmd.BackgroundCommand; import ghidra.framework.cmd.BackgroundCommand;
import ghidra.framework.model.DomainObject;
import ghidra.program.model.address.Address; import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressSetView; import ghidra.program.model.address.AddressSetView;
import ghidra.program.model.listing.*; import ghidra.program.model.listing.*;
@ -26,7 +24,7 @@ import ghidra.util.task.TaskMonitor;
/** /**
* Command for setting the fallthrough property on an instruction. * Command for setting the fallthrough property on an instruction.
*/ */
public class SetFlowOverrideCmd extends BackgroundCommand { public class SetFlowOverrideCmd extends BackgroundCommand<Program> {
Address instAddr; Address instAddr;
AddressSetView set; AddressSetView set;
FlowOverride flowOverride; FlowOverride flowOverride;
@ -60,9 +58,7 @@ public class SetFlowOverrideCmd extends BackgroundCommand {
} }
@Override @Override
public boolean applyTo(DomainObject obj, TaskMonitor monitor) { public boolean applyTo(Program program, TaskMonitor monitor) {
Program program = (Program) obj;
if (set != null) { if (set != null) {
int cnt = 0; int cnt = 0;

View file

@ -19,10 +19,10 @@ import java.math.BigInteger;
import javax.help.UnsupportedOperationException; import javax.help.UnsupportedOperationException;
import ghidra.framework.model.DomainObject;
import ghidra.program.disassemble.DisassemblerContextImpl; import ghidra.program.disassemble.DisassemblerContextImpl;
import ghidra.program.model.address.*; 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.Program;
import ghidra.program.model.listing.ProgramContext; import ghidra.program.model.listing.ProgramContext;
import ghidra.util.exception.CancelledException; import ghidra.util.exception.CancelledException;
@ -91,8 +91,7 @@ public class X86_64DisassembleCommand extends DisassembleCommand {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
public static AddressSet alignSet(int alignment, AddressSetView set) public static AddressSet alignSet(int alignment, AddressSetView set) {
throws CancelledException {
AddressSet result = new AddressSet(); AddressSet result = new AddressSet();
for (AddressRange range : set) { for (AddressRange range : set) {
Address min = range.getMinAddress(); Address min = range.getMinAddress();
@ -115,8 +114,7 @@ public class X86_64DisassembleCommand extends DisassembleCommand {
} }
@Override @Override
synchronized public boolean applyTo(DomainObject obj, TaskMonitor monitor) { synchronized public boolean applyTo(Program program, TaskMonitor monitor) {
Program program = (Program) obj;
disassemblyPerformed = false; disassemblyPerformed = false;
unalignedStart = false; unalignedStart = false;
@ -130,8 +128,8 @@ public class X86_64DisassembleCommand extends DisassembleCommand {
languageError = "Requires x86:LE:64:default"; languageError = "Requires x86:LE:64:default";
return false; return false;
} }
RegisterValue ctx = new RegisterValue(context.getBaseContextRegister()) RegisterValue ctx = new RegisterValue(context.getBaseContextRegister()).assign(longModeReg,
.assign(longModeReg, size32Mode ? BigInteger.ZERO : BigInteger.ONE); size32Mode ? BigInteger.ZERO : BigInteger.ONE);
super.setInitialContext(ctx); super.setInitialContext(ctx);

View file

@ -16,13 +16,12 @@
package ghidra.app.cmd.equate; package ghidra.app.cmd.equate;
import ghidra.framework.cmd.Command; import ghidra.framework.cmd.Command;
import ghidra.framework.model.DomainObject;
import ghidra.program.model.address.Address; import ghidra.program.model.address.Address;
import ghidra.program.model.listing.Program; import ghidra.program.model.listing.Program;
import ghidra.program.model.symbol.Equate; import ghidra.program.model.symbol.Equate;
import ghidra.program.model.symbol.EquateTable; import ghidra.program.model.symbol.EquateTable;
public class ClearEquateCmd implements Command { public class ClearEquateCmd implements Command<Program> {
private String equateName; private String equateName;
private Address addr; private Address addr;
@ -42,8 +41,8 @@ public class ClearEquateCmd implements Command {
} }
@Override @Override
public boolean applyTo(DomainObject obj) { public boolean applyTo(Program program) {
EquateTable equateTable = ((Program) obj).getEquateTable(); EquateTable equateTable = program.getEquateTable();
Equate equate = equateTable.getEquate(equateName); Equate equate = equateTable.getEquate(equateName);
clearEquate(equate, equateTable); clearEquate(equate, equateTable);

View file

@ -16,7 +16,6 @@
package ghidra.app.cmd.equate; package ghidra.app.cmd.equate;
import ghidra.framework.cmd.Command; import ghidra.framework.cmd.Command;
import ghidra.framework.model.DomainObject;
import ghidra.program.model.address.Address; import ghidra.program.model.address.Address;
import ghidra.program.model.listing.Program; import ghidra.program.model.listing.Program;
import ghidra.program.model.symbol.Equate; import ghidra.program.model.symbol.Equate;
@ -27,7 +26,7 @@ import ghidra.util.exception.InvalidInputException;
/** /**
* Command for setting an equate at a location. * Command for setting an equate at a location.
*/ */
public class SetEquateCmd implements Command { public class SetEquateCmd implements Command<Program> {
private String equateName; private String equateName;
private Address addr; private Address addr;
@ -52,23 +51,18 @@ public class SetEquateCmd implements Command {
this.equateValue = equateValue; this.equateValue = equateValue;
} }
/**
* The name of the edit action.
*/
@Override @Override
public String getName() { public String getName() {
return "Set Equate"; return "Set Equate";
} }
@Override @Override
public boolean applyTo(DomainObject obj) { public boolean applyTo(Program program) {
EquateTable equateTable = ((Program) obj).getEquateTable(); EquateTable equateTable = program.getEquateTable();
equate = equateTable.getEquate(equateName); equate = equateTable.getEquate(equateName);
if (existsWithDifferentValue(equate)) { if (existsWithDifferentValue(equate)) {
msg = msg = "Equate named " + equateName + " already exists with value of " +
"Equate named " + equateName + " already exists with value of " +
equate.getValue() + "."; equate.getValue() + ".";
return false; return false;
} }
@ -101,9 +95,6 @@ public class SetEquateCmd implements Command {
return equate; return equate;
} }
/**
* @see ghidra.framework.cmd.Command#getStatusMsg()
*/
@Override @Override
public String getStatusMsg() { public String getStatusMsg() {
return msg; return msg;

View file

@ -16,17 +16,14 @@
package ghidra.app.cmd.function; package ghidra.app.cmd.function;
import ghidra.framework.cmd.Command; 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.address.Address;
import ghidra.program.model.listing.Function; import ghidra.program.model.listing.*;
import ghidra.program.model.listing.FunctionManager;
/** /**
* Command for assigning a tag to a function. Executing this will pop up a dialog * Command for assigning a tag to a function. Executing this will pop up a dialog
* allowing the user to assign tags to a function. * allowing the user to assign tags to a function.
*/ */
public class AddFunctionTagCmd implements Command { public class AddFunctionTagCmd implements Command<Program> {
private Address entryPoint; private Address entryPoint;
private String tagName; private String tagName;
@ -44,8 +41,7 @@ public class AddFunctionTagCmd implements Command {
} }
@Override @Override
public boolean applyTo(DomainObject obj) { public boolean applyTo(Program program) {
ProgramDB program = (ProgramDB) obj;
FunctionManager functionManager = program.getFunctionManager(); FunctionManager functionManager = program.getFunctionManager();
Function function = functionManager.getFunctionAt(entryPoint); Function function = functionManager.getFunctionAt(entryPoint);

View file

@ -1,6 +1,5 @@
/* ### /* ###
* IP: GHIDRA * IP: GHIDRA
* REVIEWED: YES
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -24,12 +23,16 @@ import ghidra.util.exception.InvalidInputException;
/** /**
* A command to create a new function memory parameter. * 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 { public class AddMemoryParameterCommand extends AddParameterCommand {
private Address memAddr; private final Address memAddr;
private String name; private final String name;
private DataType dataType; private final DataType dataType;
public AddMemoryParameterCommand(Function function, Address memAddr, String name, public AddMemoryParameterCommand(Function function, Address memAddr, String name,
DataType dataType, int ordinal, SourceType source) { DataType dataType, int ordinal, SourceType source) {
@ -37,7 +40,6 @@ public class AddMemoryParameterCommand extends AddParameterCommand {
this.memAddr = memAddr; this.memAddr = memAddr;
this.name = name; this.name = name;
this.dataType = dataType; this.dataType = dataType;
this.ordinal = ordinal;
} }
@Override @Override
@ -45,9 +47,6 @@ public class AddMemoryParameterCommand extends AddParameterCommand {
return new ParameterImpl(name, dataType, memAddr, program); return new ParameterImpl(name, dataType, memAddr, program);
} }
/**
* @see ghidra.framework.cmd.Command#getName()
*/
@Override @Override
public String getName() { public String getName() {
return "Create Memory Parameter"; return "Create Memory Parameter";

View file

@ -1,6 +1,5 @@
/* ### /* ###
* IP: GHIDRA * IP: GHIDRA
* REVIEWED: YES
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -17,7 +16,6 @@
package ghidra.app.cmd.function; package ghidra.app.cmd.function;
import ghidra.framework.cmd.Command; import ghidra.framework.cmd.Command;
import ghidra.framework.model.DomainObject;
import ghidra.program.model.address.Address; import ghidra.program.model.address.Address;
import ghidra.program.model.data.DataType; import ghidra.program.model.data.DataType;
import ghidra.program.model.listing.*; import ghidra.program.model.listing.*;
@ -28,8 +26,8 @@ import ghidra.util.exception.InvalidInputException;
/** /**
* Command to add a memory variable to a function. * Command to add a memory variable to a function.
*/ */
public class AddMemoryVarCmd implements Command { public class AddMemoryVarCmd implements Command<Program> {
private Program program;
private Address memAddr; private Address memAddr;
private Address firstUseAddr; private Address firstUseAddr;
private String name; private String name;
@ -68,13 +66,8 @@ public class AddMemoryVarCmd implements Command {
this.source = source; this.source = source;
} }
/**
*
* @see ghidra.framework.cmd.Command#applyTo(ghidra.framework.model.DomainObject)
*/
@Override @Override
public boolean applyTo(DomainObject obj) { public boolean applyTo(Program program) {
program = (Program) obj;
Function f = program.getListing().getFunctionContaining(firstUseAddr); Function f = program.getListing().getFunctionContaining(firstUseAddr);
if (f == null) { if (f == null) {
@ -100,17 +93,11 @@ public class AddMemoryVarCmd implements Command {
return true; return true;
} }
/**
* @see ghidra.framework.cmd.Command#getName()
*/
@Override @Override
public String getName() { public String getName() {
return "Create Memory Variable"; return "Create Memory Variable";
} }
/**
* @see ghidra.framework.cmd.Command#getStatusMsg()
*/
@Override @Override
public String getStatusMsg() { public String getStatusMsg() {
return errMsg; return errMsg;

View file

@ -1,6 +1,5 @@
/* ### /* ###
* IP: GHIDRA * IP: GHIDRA
* REVIEWED: YES
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -17,7 +16,6 @@
package ghidra.app.cmd.function; package ghidra.app.cmd.function;
import ghidra.framework.cmd.Command; import ghidra.framework.cmd.Command;
import ghidra.framework.model.DomainObject;
import ghidra.program.model.listing.*; import ghidra.program.model.listing.*;
import ghidra.program.model.symbol.SourceType; import ghidra.program.model.symbol.SourceType;
import ghidra.util.exception.DuplicateNameException; 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 * Note: If no ordinal is provided to this class at construction time, then
* the ordinal of hte given parameter will be used. * the ordinal of hte given parameter will be used.
* *
* @see AddRegisterParameterCommand
* @see AddStackParameterCommand
* @see AddMemoryParameterCommand
* *
* @see ghidra.app.cmd.function.AddRegisterParameterCommand * @deprecated function signatures should be modified in their entirety using
* @see ghidra.app.cmd.function.AddStackParameterCommand * either {@link UpdateFunctionCommand} or {@link ApplyFunctionSignatureCmd}.
*/ */
public class AddParameterCommand implements Command { @Deprecated(since = "11.1")
public class AddParameterCommand implements Command<Program> {
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 String statusMessage;
protected int ordinal;
protected SourceType source;
public AddParameterCommand(Function function, Parameter parameter, int ordinal, public AddParameterCommand(Function function, Parameter parameter, int ordinal,
SourceType source) { SourceType source) {
@ -49,31 +53,32 @@ public class AddParameterCommand implements Command {
this.source = source; 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 // allows subclasses to use this class without having to already have
// a parameter created // a parameter created
protected AddParameterCommand(Function function, int ordinal, SourceType source) { protected AddParameterCommand(Function function, int ordinal, SourceType source) {
this(function, null, ordinal, 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 { protected Parameter getParameter(Program program) throws InvalidInputException {
return parameter; return parameter;
} }
/**
* @see ghidra.framework.cmd.Command#applyTo(ghidra.framework.model.DomainObject)
*/
@Override @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; String name = null;
try { try {
Parameter parameter2add = getParameter((Program) obj); Parameter param = getParameter(program);
name = parameter2add.getName(); name = param.getName();
if (function.insertParameter(ordinal, parameter2add, source) == null) { if (function.insertParameter(ordinal, param, source) == null) {
statusMessage = "Create parameter failed"; statusMessage = "Create parameter failed";
return false; return false;
} }
@ -102,17 +107,11 @@ public class AddParameterCommand implements Command {
return true; return true;
} }
/**
* @see ghidra.framework.cmd.Command#getStatusMsg()
*/
@Override @Override
public String getStatusMsg() { public String getStatusMsg() {
return statusMessage; return statusMessage;
} }
/**
* @see ghidra.framework.cmd.Command#getName()
*/
@Override @Override
public String getName() { public String getName() {
return "Add Parameter Command"; return "Add Parameter Command";

View file

@ -1,6 +1,5 @@
/* ### /* ###
* IP: GHIDRA * IP: GHIDRA
* REVIEWED: YES
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -25,14 +24,15 @@ import ghidra.util.exception.InvalidInputException;
/** /**
* A command to create a new function register parameter. * A command to create a new function register parameter.
* *
* * @deprecated function signatures should be modified in their entirety using
* @since Tracker Id 526 * either {@link UpdateFunctionCommand} or {@link ApplyFunctionSignatureCmd}.
*/ */
@Deprecated(since = "11.1")
public class AddRegisterParameterCommand extends AddParameterCommand { public class AddRegisterParameterCommand extends AddParameterCommand {
private Register register; private final Register register;
private String name; private final String name;
private DataType dataType; private final DataType dataType;
public AddRegisterParameterCommand(Function function, Register register, String name, public AddRegisterParameterCommand(Function function, Register register, String name,
DataType dataType, int ordinal, SourceType source) { DataType dataType, int ordinal, SourceType source) {
@ -40,7 +40,6 @@ public class AddRegisterParameterCommand extends AddParameterCommand {
this.register = register; this.register = register;
this.name = name; this.name = name;
this.dataType = dataType; this.dataType = dataType;
this.ordinal = ordinal;
} }
@Override @Override
@ -48,9 +47,6 @@ public class AddRegisterParameterCommand extends AddParameterCommand {
return new ParameterImpl(name, dataType, register, program); return new ParameterImpl(name, dataType, register, program);
} }
/**
* @see ghidra.framework.cmd.Command#getName()
*/
@Override @Override
public String getName() { public String getName() {
return "Create Register Parameter"; return "Create Register Parameter";

View file

@ -1,6 +1,5 @@
/* ### /* ###
* IP: GHIDRA * IP: GHIDRA
* REVIEWED: YES
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -17,7 +16,6 @@
package ghidra.app.cmd.function; package ghidra.app.cmd.function;
import ghidra.framework.cmd.Command; import ghidra.framework.cmd.Command;
import ghidra.framework.model.DomainObject;
import ghidra.program.model.address.Address; import ghidra.program.model.address.Address;
import ghidra.program.model.data.DataType; import ghidra.program.model.data.DataType;
import ghidra.program.model.lang.Register; import ghidra.program.model.lang.Register;
@ -30,9 +28,8 @@ import ghidra.util.exception.InvalidInputException;
* Command to add a register variable to a function. * Command to add a register variable to a function.
* *
*/ */
public class AddRegisterVarCmd implements Command { public class AddRegisterVarCmd implements Command<Program> {
private Program program;
private Address addr; private Address addr;
private Register reg; private Register reg;
private String name; private String name;
@ -71,13 +68,8 @@ public class AddRegisterVarCmd implements Command {
this.source = source; this.source = source;
} }
/**
*
* @see ghidra.framework.cmd.Command#applyTo(ghidra.framework.model.DomainObject)
*/
@Override @Override
public boolean applyTo(DomainObject obj) { public boolean applyTo(Program program) {
program = (Program) obj;
Function f = program.getListing().getFunctionContaining(addr); Function f = program.getListing().getFunctionContaining(addr);
if (f == null) { if (f == null) {

View file

@ -1,6 +1,5 @@
/* ### /* ###
* IP: GHIDRA * IP: GHIDRA
* REVIEWED: YES
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -24,14 +23,15 @@ import ghidra.util.exception.InvalidInputException;
/** /**
* A command to create a new function stack parameter. * A command to create a new function stack parameter.
* *
* * @deprecated function signatures should be modified in their entirety using
* @since Tracker Id 526 * either {@link UpdateFunctionCommand} or {@link ApplyFunctionSignatureCmd}.
*/ */
@Deprecated(since = "11.1")
public class AddStackParameterCommand extends AddParameterCommand { public class AddStackParameterCommand extends AddParameterCommand {
private int stackOffset; private final int stackOffset;
private String name; private final String name;
private DataType dataType; private final DataType dataType;
public AddStackParameterCommand(Function function, int stackOffset, String name, public AddStackParameterCommand(Function function, int stackOffset, String name,
DataType dataType, int ordinal, SourceType source) { DataType dataType, int ordinal, SourceType source) {
@ -39,8 +39,6 @@ public class AddStackParameterCommand extends AddParameterCommand {
this.stackOffset = stackOffset; this.stackOffset = stackOffset;
this.name = name; this.name = name;
this.dataType = dataType; this.dataType = dataType;
this.ordinal = ordinal;
this.source = source;
} }
@Override @Override

View file

@ -1,6 +1,5 @@
/* ### /* ###
* IP: GHIDRA * IP: GHIDRA
* REVIEWED: YES
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -17,7 +16,6 @@
package ghidra.app.cmd.function; package ghidra.app.cmd.function;
import ghidra.framework.cmd.Command; import ghidra.framework.cmd.Command;
import ghidra.framework.model.DomainObject;
import ghidra.program.model.address.Address; import ghidra.program.model.address.Address;
import ghidra.program.model.data.DataType; import ghidra.program.model.data.DataType;
import ghidra.program.model.listing.*; import ghidra.program.model.listing.*;
@ -28,8 +26,8 @@ import ghidra.util.exception.InvalidInputException;
/** /**
* Command to add a stack variable to a function. * Command to add a stack variable to a function.
*/ */
public class AddStackVarCmd implements Command { public class AddStackVarCmd implements Command<Program> {
private Program program;
private Address addr; private Address addr;
private int stackOffset; private int stackOffset;
private String name; private String name;
@ -37,7 +35,6 @@ public class AddStackVarCmd implements Command {
private SourceType source; private SourceType source;
private String errMsg = ""; private String errMsg = "";
/** /**
* Constructs a new command to add a stack variable to a function. * Constructs a new command to add a stack variable to a function.
* @param addr initial declaration point of variable. * @param addr initial declaration point of variable.
@ -46,7 +43,8 @@ public class AddStackVarCmd implements Command {
* @param dataType variable data-type or null for a default data type of minimal size * @param dataType variable data-type or null for a default data type of minimal size
* @param source the source of this stack variable * @param source the source of this stack variable
*/ */
public AddStackVarCmd(Address addr, int stackOffset, String name, DataType dataType, SourceType source) { public AddStackVarCmd(Address addr, int stackOffset, String name, DataType dataType,
SourceType source) {
this.addr = addr; this.addr = addr;
this.stackOffset = stackOffset; this.stackOffset = stackOffset;
this.name = name; this.name = name;
@ -54,12 +52,8 @@ public class AddStackVarCmd implements Command {
this.source = source; this.source = source;
} }
/** @Override
* public boolean applyTo(Program program) {
* @see ghidra.framework.cmd.Command#applyTo(ghidra.framework.model.DomainObject)
*/
public boolean applyTo(DomainObject obj) {
program = (Program)obj;
if (dataType != null) { if (dataType != null) {
dataType = dataType.clone(program.getDataTypeManager()); dataType = dataType.clone(program.getDataTypeManager());
} }
@ -77,26 +71,24 @@ public class AddStackVarCmd implements Command {
errMsg = "Create stack variable failed"; errMsg = "Create stack variable failed";
return false; return false;
} }
} catch (DuplicateNameException e) { }
catch (DuplicateNameException e) {
errMsg = "Variable named " + name + " already exists"; errMsg = "Variable named " + name + " already exists";
return false; return false;
} catch (InvalidInputException e) { }
catch (InvalidInputException e) {
errMsg = e.getMessage(); errMsg = e.getMessage();
return false; return false;
} }
return true; return true;
} }
/** @Override
* @see ghidra.framework.cmd.Command#getName()
*/
public String getName() { public String getName() {
return "Create Stack Variable"; return "Create Stack Variable";
} }
/** @Override
* @see ghidra.framework.cmd.Command#getStatusMsg()
*/
public String getStatusMsg() { public String getStatusMsg() {
return errMsg; return errMsg;
} }

View file

@ -20,7 +20,6 @@ import java.util.*;
import ghidra.app.cmd.disassemble.DisassembleCommand; import ghidra.app.cmd.disassemble.DisassembleCommand;
import ghidra.app.util.PseudoDisassembler; import ghidra.app.util.PseudoDisassembler;
import ghidra.framework.cmd.BackgroundCommand; import ghidra.framework.cmd.BackgroundCommand;
import ghidra.framework.model.DomainObject;
import ghidra.program.model.address.Address; import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressSetView; import ghidra.program.model.address.AddressSetView;
import ghidra.program.model.data.*; 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 * any user defined label that has the same name as the function
* signature. * signature.
*/ */
public class ApplyFunctionDataTypesCmd extends BackgroundCommand { public class ApplyFunctionDataTypesCmd extends BackgroundCommand<Program> {
private Program program; private Program program;
private BookmarkManager bookmarkMgr; private BookmarkManager bookmarkMgr;
private List<Category> sourceCategories; private List<Category> sourceCategories;
@ -83,8 +82,8 @@ public class ApplyFunctionDataTypesCmd extends BackgroundCommand {
* @param createBookmarksEnabled true to create a bookmark when a function signature * @param createBookmarksEnabled true to create a bookmark when a function signature
* has been applied. * has been applied.
*/ */
public ApplyFunctionDataTypesCmd(Category sourceCategory, AddressSetView set, public ApplyFunctionDataTypesCmd(Category sourceCategory, AddressSetView set, SourceType source,
SourceType source, boolean alwaysReplace, boolean createBookmarksEnabled) { boolean alwaysReplace, boolean createBookmarksEnabled) {
super("Apply Function Data Types", true, false, false); super("Apply Function Data Types", true, false, false);
this.sourceCategories = List.of(sourceCategory); this.sourceCategories = List.of(sourceCategory);
this.addresses = set; this.addresses = set;
@ -102,8 +101,8 @@ public class ApplyFunctionDataTypesCmd extends BackgroundCommand {
} }
@Override @Override
public boolean applyTo(DomainObject obj, TaskMonitor monitor) { public boolean applyTo(Program p, TaskMonitor monitor) {
program = (Program) obj; program = p;
bookmarkMgr = program.getBookmarkManager(); bookmarkMgr = program.getBookmarkManager();
monitor.setMessage("Applying Function Signatures"); 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 * @param symbolMap symbol map where possible function definitions may be applied
* @throws CancelledException if task cancelled * @throws CancelledException if task cancelled
*/ */
private void applyFunctionDefinitions(TaskMonitor monitor, private void applyFunctionDefinitions(TaskMonitor monitor, Map<String, List<Symbol>> symbolMap)
Map<String, List<Symbol>> symbolMap) throws CancelledException { throws CancelledException {
Map<String, FunctionDefinition> functionNameMap = new HashMap<>(); Map<String, FunctionDefinition> functionNameMap = new HashMap<>();
for (Category cat : sourceCategories) { for (Category cat : sourceCategories) {
@ -399,7 +398,7 @@ public class ApplyFunctionDataTypesCmd extends BackgroundCommand {
* *
* @param symbolMap map of symbol names to all matching symbols * @param symbolMap map of symbol names to all matching symbols
* @param prefix optional prefix on symbol to lookup * @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 * @return symbol definition; null if no symbol is found for the given name
*/ */
private List<Symbol> lookupSymbol(Map<String, List<Symbol>> symbolMap, String prefix, private List<Symbol> lookupSymbol(Map<String, List<Symbol>> symbolMap, String prefix,

View file

@ -19,7 +19,6 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import ghidra.framework.cmd.BackgroundCommand; import ghidra.framework.cmd.BackgroundCommand;
import ghidra.framework.model.DomainObject;
import ghidra.program.model.address.Address; import ghidra.program.model.address.Address;
import ghidra.program.model.data.*; import ghidra.program.model.data.*;
import ghidra.program.model.lang.CompilerSpec; 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. * 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<Program> {
private Address entryPt; private Address entryPt;
private SourceType source; private SourceType source;
private FunctionRenameOption functionRenameOption; private FunctionRenameOption functionRenameOption;
@ -159,8 +160,8 @@ public class ApplyFunctionSignatureCmd extends BackgroundCommand {
} }
@Override @Override
public boolean applyTo(DomainObject obj, TaskMonitor monitor) { public boolean applyTo(Program p, TaskMonitor monitor) {
program = (Program) obj; this.program = p;
Function func = program.getListing().getFunctionContaining(entryPt); Function func = program.getListing().getFunctionContaining(entryPt);

View file

@ -15,16 +15,17 @@
*/ */
package ghidra.app.cmd.function; 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.address.*;
import ghidra.program.model.block.CodeBlock; 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.listing.*;
import ghidra.program.model.pcode.*; import ghidra.program.model.pcode.*;
import ghidra.program.model.scalar.Scalar; import ghidra.program.model.scalar.Scalar;
import ghidra.program.model.symbol.FlowType; import ghidra.program.model.symbol.FlowType;
import ghidra.program.model.symbol.Reference;
import ghidra.program.model.util.*; import ghidra.program.model.util.*;
import ghidra.program.util.*; import ghidra.program.util.*;
import ghidra.program.util.SymbolicPropogator.Value; import ghidra.program.util.SymbolicPropogator.Value;
@ -33,13 +34,6 @@ import ghidra.util.exception.*;
import ghidra.util.task.TaskMonitor; 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 * 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 * 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 * 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. * 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 * Each equation represents the stack change for a given basic flow block or
* call instruction within the function. * call instruction within the function.
*
*
*/ */
public class CallDepthChangeInfo { public class CallDepthChangeInfo {
Program program; Program program;
@ -142,17 +133,10 @@ public class CallDepthChangeInfo {
public CallDepthChangeInfo(Program program, Address addr, AddressSetView restrictSet, public CallDepthChangeInfo(Program program, Address addr, AddressSetView restrictSet,
Register frameReg, TaskMonitor monitor) throws CancelledException { Register frameReg, TaskMonitor monitor) throws CancelledException {
Function func = program.getFunctionManager().getFunctionContaining(addr); Function func = program.getFunctionManager().getFunctionContaining(addr);
Register stackReg = program.getCompilerSpec().getStackPointer(); Register stackPtrReg = program.getCompilerSpec().getStackPointer();
initialize(func, restrictSet, stackReg, monitor); 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, private void initialize(Function func, AddressSetView restrictSet, Register reg,
TaskMonitor monitor) throws CancelledException { TaskMonitor monitor) throws CancelledException {
changeMap = new DefaultIntPropertyMap("change"); changeMap = new DefaultIntPropertyMap("change");
@ -177,6 +161,7 @@ public class CallDepthChangeInfo {
i = changeMap.getInt(addr); i = changeMap.getInt(addr);
} }
catch (NoValueException exc) { catch (NoValueException exc) {
// ignore
} }
return i; return i;
@ -196,6 +181,7 @@ public class CallDepthChangeInfo {
depth = depthMap.getInt(addr); depth = depthMap.getInt(addr);
} }
catch (NoValueException exc) { catch (NoValueException exc) {
// ignore
} }
return depth; return depth;
} }
@ -221,6 +207,8 @@ public class CallDepthChangeInfo {
* unknown. * unknown.
* *
* @param instr instruction to analyze * @param instr instruction to analyze
* @param procContext
* @param currentStackDepth
* *
* @return int change to stack depth if it can be determined, * @return int change to stack depth if it can be determined,
* Function.UNKNOWN_STACK_DEPTH_CHANGE otherwise. * Function.UNKNOWN_STACK_DEPTH_CHANGE otherwise.
@ -396,7 +384,6 @@ public class CallDepthChangeInfo {
return false; return false;
} }
/** /**
* Gets the stack depth change value that has been set at the indicated address. * 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); return ipm.getPropertyIterator(addressSet);
} }
/** /**
* Follow the flows of the subroutine, accumulating information about the * Follow the flows of the subroutine, accumulating information about the
* stack pointer and any other register the stack pointer is assigned to. * stack pointer and any other register the stack pointer is assigned to.
@ -512,7 +498,8 @@ public class CallDepthChangeInfo {
try { try {
stackValue = context.getValue(stackRegVarnode, true, this); 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(); int stackPointerDepth = (int) stackValue.getOffset();
setDepth(instr, stackPointerDepth); setDepth(instr, stackPointerDepth);
} }
@ -580,7 +567,6 @@ public class CallDepthChangeInfo {
return; return;
} }
public int getStackPurge() { public int getStackPurge() {
return stackPurge; return stackPurge;
} }

View file

@ -16,7 +16,6 @@
package ghidra.app.cmd.function; package ghidra.app.cmd.function;
import ghidra.framework.cmd.BackgroundCommand; import ghidra.framework.cmd.BackgroundCommand;
import ghidra.framework.model.DomainObject;
import ghidra.program.model.address.AddressSetView; import ghidra.program.model.address.AddressSetView;
import ghidra.program.model.data.*; import ghidra.program.model.data.*;
import ghidra.program.model.listing.*; 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 * Capture all selected function signature data types from the current program and put them
* in the data type manager. * in the data type manager.
*/ */
public class CaptureFunctionDataTypesCmd extends BackgroundCommand { public class CaptureFunctionDataTypesCmd extends BackgroundCommand<Program> {
private Program program;
private DataTypeManager dtm; private DataTypeManager dtm;
private AddressSetView set; private AddressSetView set;
private CaptureFunctionDataTypesListener listener; private CaptureFunctionDataTypesListener listener;
@ -40,6 +39,7 @@ public class CaptureFunctionDataTypesCmd extends BackgroundCommand {
* @param dtm data type manager containing the function signature data types * @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 * @param set set of addresses containing the entry points of the functions whose signatures
* are to be turned into data types. * are to be turned into data types.
* @param listener
*/ */
public CaptureFunctionDataTypesCmd(DataTypeManager dtm, AddressSetView set, public CaptureFunctionDataTypesCmd(DataTypeManager dtm, AddressSetView set,
CaptureFunctionDataTypesListener listener) { CaptureFunctionDataTypesListener listener) {
@ -49,13 +49,8 @@ public class CaptureFunctionDataTypesCmd extends BackgroundCommand {
this.listener = listener; this.listener = listener;
} }
/**
*
* @see ghidra.framework.cmd.BackgroundCommand#applyTo(ghidra.framework.model.DomainObject, ghidra.util.task.TaskMonitor)
*/
@Override @Override
public boolean applyTo(DomainObject obj, TaskMonitor monitor) { public boolean applyTo(Program program, TaskMonitor monitor) {
program = (Program) obj;
monitor.setMessage("Capturing Function Data Types"); monitor.setMessage("Capturing Function Data Types");
boolean success = false; boolean success = false;

View file

@ -16,14 +16,12 @@
package ghidra.app.cmd.function; package ghidra.app.cmd.function;
import ghidra.framework.cmd.Command; import ghidra.framework.cmd.Command;
import ghidra.framework.model.DomainObject;
import ghidra.program.database.ProgramDB;
import ghidra.program.model.listing.*; import ghidra.program.model.listing.*;
/** /**
* Updates the name or comment field for a given function tag * Updates the name or comment field for a given function tag
*/ */
public class ChangeFunctionTagCmd implements Command { public class ChangeFunctionTagCmd implements Command<Program> {
private final int field; private final int field;
private final String tagName; private final String tagName;
@ -51,8 +49,8 @@ public class ChangeFunctionTagCmd implements Command {
} }
@Override @Override
public boolean applyTo(DomainObject obj) { public boolean applyTo(Program program) {
ProgramDB program = (ProgramDB) obj;
FunctionManager functionManager = program.getFunctionManager(); FunctionManager functionManager = program.getFunctionManager();
FunctionTagManager tagManager = functionManager.getFunctionTagManager(); FunctionTagManager tagManager = functionManager.getFunctionTagManager();
FunctionTag tag = tagManager.getFunctionTag(tagName); FunctionTag tag = tagManager.getFunctionTag(tagName);

View file

@ -16,14 +16,13 @@
package ghidra.app.cmd.function; package ghidra.app.cmd.function;
import ghidra.framework.cmd.Command; import ghidra.framework.cmd.Command;
import ghidra.framework.model.DomainObject;
import ghidra.program.model.address.Address; import ghidra.program.model.address.Address;
import ghidra.program.model.listing.*; import ghidra.program.model.listing.*;
import ghidra.program.model.symbol.*; import ghidra.program.model.symbol.*;
import ghidra.util.exception.DuplicateNameException; import ghidra.util.exception.DuplicateNameException;
import ghidra.util.exception.InvalidInputException; import ghidra.util.exception.InvalidInputException;
public class CreateExternalFunctionCmd implements Command { public class CreateExternalFunctionCmd implements Command<Program> {
private Symbol extSymbol; 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 libraryName library name, if null the UNKNOWN library will be used
* @param name function name (required) * @param name function name (required)
* @param address the address of the function's entry point in the external library (optional) * @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, public CreateExternalFunctionCmd(String libraryName, String name, Address address,
SourceType source) { SourceType source) {
@ -94,8 +94,8 @@ public class CreateExternalFunctionCmd implements Command {
} }
@Override @Override
public boolean applyTo(DomainObject obj) { public boolean applyTo(Program program) {
Program program = (Program) obj;
if (extSymbol == null) { if (extSymbol == null) {
return createExternalFunction(program); return createExternalFunction(program);
} }

View file

@ -16,16 +16,17 @@
package ghidra.app.cmd.function; package ghidra.app.cmd.function;
import java.util.*; import java.util.*;
import java.util.Map.Entry;
import ghidra.framework.cmd.BackgroundCommand; import ghidra.framework.cmd.BackgroundCommand;
import ghidra.framework.model.DomainObject;
import ghidra.program.database.function.OverlappingFunctionException; import ghidra.program.database.function.OverlappingFunctionException;
import ghidra.program.model.address.*; 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.listing.*;
import ghidra.program.model.symbol.*; import ghidra.program.model.symbol.*;
import ghidra.util.Msg; import ghidra.util.Msg;
import ghidra.util.exception.*; import ghidra.util.exception.CancelledException;
import ghidra.util.exception.InvalidInputException;
import ghidra.util.task.TaskMonitor; 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 * parameters used to create the function (Selection or just an address) and
* create the function on redo and clear on undo. * create the function on redo and clear on undo.
*/ */
public class CreateFunctionCmd extends BackgroundCommand { public class CreateFunctionCmd extends BackgroundCommand<Program> {
private AddressSetView origEntries; private AddressSetView origEntries;
private AddressSetView origBody; private AddressSetView origBody;
@ -143,13 +144,9 @@ public class CreateFunctionCmd extends BackgroundCommand {
this(null, entry, null, SourceType.DEFAULT, findEntryPoint, false); this(null, entry, null, SourceType.DEFAULT, findEntryPoint, false);
} }
/**
*
* @see ghidra.framework.cmd.BackgroundCommand#applyTo(ghidra.framework.model.DomainObject, ghidra.util.task.TaskMonitor)
*/
@Override @Override
public boolean applyTo(DomainObject obj, TaskMonitor monitor) { public boolean applyTo(Program p, TaskMonitor monitor) {
program = (Program) obj; program = p;
Namespace globalNameSpace = program.getGlobalNamespace(); Namespace globalNameSpace = program.getGlobalNamespace();
@ -181,7 +178,7 @@ public class CreateFunctionCmd extends BackgroundCommand {
extFunc = ((ExternalLocation) symObj).createFunction(); extFunc = ((ExternalLocation) symObj).createFunction();
} }
else { else {
Msg.error(this, "Unexpected external symbol object: " + obj.getClass()); Msg.error(this, "Unexpected external symbol object: " + symObj.getClass());
continue; continue;
} }
if (funcName != null) { if (funcName != null) {
@ -215,7 +212,8 @@ public class CreateFunctionCmd extends BackgroundCommand {
try { try {
didCreate = createFunction(monitor, funcName, nameSpace, origEntry, didCreate = createFunction(monitor, funcName, nameSpace, origEntry,
origBody, tmpSource); origBody, tmpSource);
} catch (OverlappingFunctionException e) { }
catch (OverlappingFunctionException e) {
// try to create again, sometimes thunks can get resolved that // try to create again, sometimes thunks can get resolved that
// can't be detected, for example a thunk->function->thunk // can't be detected, for example a thunk->function->thunk
// where the final thunk gets created // 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 OverlappingFunctionException if new function overlaps with existing and couldn't fix
* @throws InvalidInputException bad characters in function name * @throws InvalidInputException bad characters in function name
*/ */
private boolean createFunction(TaskMonitor monitor, String funcName, private boolean createFunction(TaskMonitor monitor, String funcName, Namespace nameSpace,
Namespace nameSpace, Address entry, AddressSetView body, Address entry, AddressSetView body, SourceType nameSource)
SourceType nameSource) throws InvalidInputException, throws InvalidInputException, OverlappingFunctionException, CancelledException {
OverlappingFunctionException, CancelledException {
FunctionManager functionMgr = program.getFunctionManager(); FunctionManager functionMgr = program.getFunctionManager();
@ -356,8 +353,7 @@ public class CreateFunctionCmd extends BackgroundCommand {
*/ */
private boolean createFunction(Namespace nameSpace, String funcName, Address entry, private boolean createFunction(Namespace nameSpace, String funcName, Address entry,
AddressSetView body, SourceType nameSource, Map<Function, AddressSetView> bodyChangeMap, AddressSetView body, SourceType nameSource, Map<Function, AddressSetView> bodyChangeMap,
TaskMonitor monitor) TaskMonitor monitor) throws OverlappingFunctionException, InvalidInputException {
throws OverlappingFunctionException, InvalidInputException {
Listing listing = program.getListing(); Listing listing = program.getListing();
@ -408,9 +404,9 @@ public class CreateFunctionCmd extends BackgroundCommand {
* @throws CancelledException user cancelled * @throws CancelledException user cancelled
* @throws OverlappingFunctionException existing functions overlap and couldn't reconcile * @throws OverlappingFunctionException existing functions overlap and couldn't reconcile
*/ */
private static AddressSetView subtractBodyFromExisting(Program program, Address entry, AddressSetView newFuncBody, private static AddressSetView subtractBodyFromExisting(Program program, Address entry,
Map<Function, AddressSetView> bodyChangeMap, TaskMonitor monitor) AddressSetView newFuncBody, Map<Function, AddressSetView> bodyChangeMap,
throws CancelledException, OverlappingFunctionException { TaskMonitor monitor) throws CancelledException, OverlappingFunctionException {
// get all functions that overlap new function body // get all functions that overlap new function body
Iterator<Function> iter = program.getFunctionManager().getFunctionsOverlapping(newFuncBody); Iterator<Function> iter = program.getFunctionManager().getFunctionsOverlapping(newFuncBody);
@ -437,19 +433,22 @@ public class CreateFunctionCmd extends BackgroundCommand {
if (overlapEntryPoint.compareTo(entry) < 0) { if (overlapEntryPoint.compareTo(entry) < 0) {
// overlap function is before, subtract from entry to end of new function // overlap function is before, subtract from entry to end of new function
overlapEndAddr = newFuncBody.getMaxAddress(); overlapEndAddr = newFuncBody.getMaxAddress();
} else { }
else {
// overlap function is after, subtract from entry to entry of overlapping function // overlap function is after, subtract from entry to entry of overlapping function
overlapEndAddr = overlapEntryPoint.previous(); overlapEndAddr = overlapEntryPoint.previous();
} }
AddressSet overlapAddrsShouldBeInNewFunction = new AddressSet(entry, overlapEndAddr); AddressSet overlapAddrsShouldBeInNewFunction = new AddressSet(entry, overlapEndAddr);
AddressSetView newOverlapFuncBody = overlapFuncBody.subtract(overlapAddrsShouldBeInNewFunction); AddressSetView newOverlapFuncBody =
overlapFuncBody.subtract(overlapAddrsShouldBeInNewFunction);
try { try {
if (!overlapFuncBody.equals(newOverlapFuncBody)) { if (!overlapFuncBody.equals(newOverlapFuncBody)) {
overlapFunc.setBody(newOverlapFuncBody); // set overlap body with new function body addresses removed overlapFunc.setBody(newOverlapFuncBody); // set overlap body with new function body addresses removed
bodyChangeMap.put(overlapFunc, overlapFuncBody); // save old overlap body bodyChangeMap.put(overlapFunc, overlapFuncBody); // save old overlap body
} }
overlapFuncBody = newOverlapFuncBody; overlapFuncBody = newOverlapFuncBody;
} catch (OverlappingFunctionException oe) { }
catch (OverlappingFunctionException oe) {
// do nothing, will just subtract entire overlapping body from new function body // do nothing, will just subtract entire overlapping body from new function body
} }
@ -524,9 +523,7 @@ public class CreateFunctionCmd extends BackgroundCommand {
*/ */
private static void restoreOriginalBodies(Map<Function, AddressSetView> bodyChangeMap) { private static void restoreOriginalBodies(Map<Function, AddressSetView> bodyChangeMap) {
Set<Map.Entry<Function, AddressSetView>> entries = bodyChangeMap.entrySet(); Set<Map.Entry<Function, AddressSetView>> entries = bodyChangeMap.entrySet();
Iterator<Map.Entry<Function, AddressSetView>> iter = entries.iterator(); for (Entry<Function, AddressSetView> entry : entries) {
while (iter.hasNext()) {
Map.Entry<Function, AddressSetView> entry = iter.next();
try { try {
entry.getKey().setBody(entry.getValue()); entry.getKey().setBody(entry.getValue());
} }

View file

@ -17,7 +17,6 @@ package ghidra.app.cmd.function;
import ghidra.app.services.DataTypeManagerService; import ghidra.app.services.DataTypeManagerService;
import ghidra.framework.cmd.Command; import ghidra.framework.cmd.Command;
import ghidra.framework.model.DomainObject;
import ghidra.framework.plugintool.ServiceProvider; import ghidra.framework.plugintool.ServiceProvider;
import ghidra.framework.store.FileSystem; import ghidra.framework.store.FileSystem;
import ghidra.program.model.address.Address; 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 * Command for creating a function definition data type based on the
* function signature for a function at an address. * function signature for a function at an address.
*/ */
public class CreateFunctionDefinitionCmd implements Command { public class CreateFunctionDefinitionCmd implements Command<Program> {
private Address entry; private Address entry;
private final ServiceProvider serviceProvider; private final ServiceProvider serviceProvider;
private String statusMsg = ""; private String statusMsg = "";
@ -37,28 +36,23 @@ public class CreateFunctionDefinitionCmd implements Command {
* Constructs a new command for creating a function definition. * Constructs a new command for creating a function definition.
* @param entry entry point address for the function whose signature is to * @param entry entry point address for the function whose signature is to
* be used to create the function defintion data type. * 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) { public CreateFunctionDefinitionCmd(Address entry, ServiceProvider serviceProvider) {
this.entry = entry; this.entry = entry;
this.serviceProvider = serviceProvider; this.serviceProvider = serviceProvider;
} }
/**
*
* @see ghidra.framework.cmd.Command#getName()
*/
@Override @Override
public String getName() { public String getName() {
return "Create Function Definition"; return "Create Function Definition";
} }
/**
*
* @see ghidra.framework.cmd.Command#applyTo(ghidra.framework.model.DomainObject)
*/
@Override @Override
public boolean applyTo(DomainObject obj) { public boolean applyTo(Program program) {
Program program = (Program) obj;
// save off the function signature // save off the function signature
// get the body, comment, stack, return type // get the body, comment, stack, return type
Listing listing = program.getListing(); Listing listing = program.getListing();
@ -83,17 +77,16 @@ public class CreateFunctionDefinitionCmd implements Command {
FunctionDefinitionDataType functionDef = new FunctionDefinitionDataType(sig); FunctionDefinitionDataType functionDef = new FunctionDefinitionDataType(sig);
DataType newType = dtm.resolve(functionDef, null); DataType newType = dtm.resolve(functionDef, null);
DataTypeManagerService service = serviceProvider.getService(DataTypeManagerService.class); if (serviceProvider != null) {
DataTypeManagerService service =
serviceProvider.getService(DataTypeManagerService.class);
if (service != null) { if (service != null) {
service.setDataTypeSelected(newType); service.setDataTypeSelected(newType);
} }
}
return true; return true;
} }
/**
* @see ghidra.framework.cmd.Command#getStatusMsg()
*/
@Override @Override
public String getStatusMsg() { public String getStatusMsg() {
return statusMsg; return statusMsg;

View file

@ -16,15 +16,12 @@
package ghidra.app.cmd.function; package ghidra.app.cmd.function;
import ghidra.framework.cmd.Command; import ghidra.framework.cmd.Command;
import ghidra.framework.model.DomainObject; import ghidra.program.model.listing.*;
import ghidra.program.database.ProgramDB;
import ghidra.program.model.listing.FunctionManager;
import ghidra.program.model.listing.FunctionTagManager;
/** /**
* Command for assigning a tag to a function * Command for assigning a tag to a function
*/ */
public class CreateFunctionTagCmd implements Command { public class CreateFunctionTagCmd implements Command<Program> {
private String name; private String name;
private String comment; private String comment;
@ -51,8 +48,7 @@ public class CreateFunctionTagCmd implements Command {
} }
@Override @Override
public boolean applyTo(DomainObject obj) { public boolean applyTo(Program program) {
ProgramDB program = (ProgramDB) obj;
FunctionManager functionManager = program.getFunctionManager(); FunctionManager functionManager = program.getFunctionManager();
FunctionTagManager tagManager = functionManager.getFunctionTagManager(); FunctionTagManager tagManager = functionManager.getFunctionTagManager();
tagManager.createFunctionTag(name, comment); tagManager.createFunctionTag(name, comment);

View file

@ -16,7 +16,6 @@
package ghidra.app.cmd.function; package ghidra.app.cmd.function;
import ghidra.framework.cmd.BackgroundCommand; import ghidra.framework.cmd.BackgroundCommand;
import ghidra.framework.model.DomainObject;
import ghidra.program.model.address.*; import ghidra.program.model.address.*;
import ghidra.program.model.listing.*; import ghidra.program.model.listing.*;
import ghidra.program.model.symbol.SourceType; import ghidra.program.model.symbol.SourceType;
@ -31,9 +30,8 @@ import ghidra.util.task.TaskMonitor;
* also discarded. * also discarded.
* *
*/ */
public class CreateMultipleFunctionsCmd extends BackgroundCommand { public class CreateMultipleFunctionsCmd extends BackgroundCommand<Program> {
private Program program;
private AddressSetView selection; private AddressSetView selection;
private SourceType source; private SourceType source;
@ -44,8 +42,7 @@ public class CreateMultipleFunctionsCmd extends BackgroundCommand {
} }
@Override @Override
public boolean applyTo(DomainObject obj, TaskMonitor monitor) { public boolean applyTo(Program program, TaskMonitor monitor) {
program = (Program) obj;
Listing listing = program.getListing(); Listing listing = program.getListing();
AddressSet addressSet = new AddressSet(selection); AddressSet addressSet = new AddressSet(selection);
@ -60,8 +57,10 @@ public class CreateMultipleFunctionsCmd extends BackgroundCommand {
Function function = listing.getFunctionContaining(address); Function function = listing.getFunctionContaining(address);
if (function == null) { if (function == null) {
// Create the next function. // Create the next function.
Function createdFunction = createFunction(address, program, monitor); CreateFunctionCmd createFunctionCmd =
if (createdFunction != null) { new CreateFunctionCmd(null, address, null, source);
if (createFunctionCmd.applyTo(program, monitor)) {
function = createFunctionCmd.getFunction();
functionsCreated++; functionsCreated++;
} }
} }
@ -83,19 +82,4 @@ public class CreateMultipleFunctionsCmd extends BackgroundCommand {
return true; 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;
}
} }

View file

@ -21,7 +21,6 @@ import java.util.concurrent.atomic.AtomicInteger;
import ghidra.app.util.PseudoDisassembler; import ghidra.app.util.PseudoDisassembler;
import ghidra.framework.cmd.BackgroundCommand; import ghidra.framework.cmd.BackgroundCommand;
import ghidra.framework.model.DomainObject;
import ghidra.program.database.function.OverlappingFunctionException; import ghidra.program.database.function.OverlappingFunctionException;
import ghidra.program.model.address.*; import ghidra.program.model.address.*;
import ghidra.program.model.block.*; import ghidra.program.model.block.*;
@ -40,7 +39,7 @@ import ghidra.util.task.TaskMonitor;
/** /**
* Command for creating a thunk function at an address. * Command for creating a thunk function at an address.
*/ */
public class CreateThunkFunctionCmd extends BackgroundCommand { public class CreateThunkFunctionCmd extends BackgroundCommand<Program> {
private Address entry; private Address entry;
private AddressSetView body; private AddressSetView body;
private Address referencedFunctionAddr; private Address referencedFunctionAddr;
@ -144,8 +143,7 @@ public class CreateThunkFunctionCmd extends BackgroundCommand {
} }
@Override @Override
public boolean applyTo(DomainObject obj, TaskMonitor monitor) { public boolean applyTo(Program program, TaskMonitor monitor) {
Program program = (Program) obj;
FunctionManager functionMgr = program.getFunctionManager(); FunctionManager functionMgr = program.getFunctionManager();
@ -401,7 +399,8 @@ public class CreateThunkFunctionCmd extends BackgroundCommand {
return destRef.getDestinationAddress(); return destRef.getDestinationAddress();
} }
} }
} catch (CancelledException e) { }
catch (CancelledException e) {
// ignore // ignore
} }
@ -468,7 +467,8 @@ public class CreateThunkFunctionCmd extends BackgroundCommand {
new ContextEvaluatorAdapter() { new ContextEvaluatorAdapter() {
@Override @Override
public boolean evaluateReference(VarnodeContext context, Instruction instr, 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. // go ahead and place the reference, since it is a constant.
if (refType.isComputed() && refType.isFlow() && if (refType.isComputed() && refType.isFlow() &&
program.getMemory().contains(address)) { program.getMemory().contains(address)) {
@ -494,8 +494,7 @@ public class CreateThunkFunctionCmd extends BackgroundCommand {
if (value != null && program.getListing().getInstructionAt(addr) == null) { if (value != null && program.getListing().getInstructionAt(addr) == null) {
try { try {
program.getProgramContext() program.getProgramContext()
.setValue(isaModeRegister, addr, addr, .setValue(isaModeRegister, addr, addr, value);
value);
} }
catch (ContextChangeException e) { catch (ContextChangeException e) {
// ignore // ignore

View file

@ -16,14 +16,13 @@
package ghidra.app.cmd.function; package ghidra.app.cmd.function;
import ghidra.framework.cmd.Command; import ghidra.framework.cmd.Command;
import ghidra.framework.model.DomainObject;
import ghidra.program.model.address.Address; import ghidra.program.model.address.Address;
import ghidra.program.model.listing.*; import ghidra.program.model.listing.*;
/** /**
* Command for clearing a function at an address. * Command for clearing a function at an address.
*/ */
public class DeleteFunctionCmd implements Command { public class DeleteFunctionCmd implements Command<Program> {
private Address entry; private Address entry;
private boolean ignoreMissingFunction; private boolean ignoreMissingFunction;
@ -40,21 +39,14 @@ public class DeleteFunctionCmd implements Command {
this.ignoreMissingFunction = ignoreMissingFunction; this.ignoreMissingFunction = ignoreMissingFunction;
} }
/**
*
* @see ghidra.framework.cmd.Command#getName()
*/
@Override @Override
public String getName() { public String getName() {
return "Delete Function"; return "Delete Function";
} }
/**
* @see ghidra.framework.cmd.Command#applyTo(ghidra.framework.model.DomainObject)
*/
@Override @Override
public boolean applyTo(DomainObject obj) { public boolean applyTo(Program program) {
Program program = (Program) obj;
// save off the function signature // save off the function signature
// get the body, comment, stack, return type // get the body, comment, stack, return type
Listing listing = program.getListing(); Listing listing = program.getListing();
@ -75,9 +67,6 @@ public class DeleteFunctionCmd implements Command {
return true; return true;
} }
/**
* @see ghidra.framework.cmd.Command#getStatusMsg()
*/
@Override @Override
public String getStatusMsg() { public String getStatusMsg() {
return ""; return "";

View file

@ -16,16 +16,13 @@
package ghidra.app.cmd.function; package ghidra.app.cmd.function;
import ghidra.framework.cmd.BackgroundCommand; import ghidra.framework.cmd.BackgroundCommand;
import ghidra.framework.model.DomainObject; import ghidra.program.model.listing.*;
import ghidra.program.database.ProgramDB;
import ghidra.program.model.listing.FunctionManager;
import ghidra.program.model.listing.FunctionTag;
import ghidra.util.task.TaskMonitor; import ghidra.util.task.TaskMonitor;
/** /**
* Command for deleting a tag from the system * Command for deleting a tag from the system
*/ */
public class DeleteFunctionTagCmd extends BackgroundCommand { public class DeleteFunctionTagCmd extends BackgroundCommand<Program> {
private String tagName; private String tagName;
@ -39,9 +36,7 @@ public class DeleteFunctionTagCmd extends BackgroundCommand {
} }
@Override @Override
public boolean applyTo(DomainObject obj, TaskMonitor monitor) { public boolean applyTo(Program program, TaskMonitor monitor) {
ProgramDB program = (ProgramDB) obj;
FunctionManager functionManager = program.getFunctionManager(); FunctionManager functionManager = program.getFunctionManager();
FunctionTag tag = functionManager.getFunctionTagManager().getFunctionTag(tagName); FunctionTag tag = functionManager.getFunctionTagManager().getFunctionTag(tagName);
if (tag != null) { if (tag != null) {

View file

@ -1,6 +1,5 @@
/* ### /* ###
* IP: GHIDRA * IP: GHIDRA
* REVIEWED: YES
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -17,13 +16,12 @@
package ghidra.app.cmd.function; package ghidra.app.cmd.function;
import ghidra.framework.cmd.Command; import ghidra.framework.cmd.Command;
import ghidra.framework.model.DomainObject;
import ghidra.program.model.listing.*; import ghidra.program.model.listing.*;
/** /**
* Command for deleting a variable in a function. * Command for deleting a variable in a function.
*/ */
public class DeleteVariableCmd implements Command { public class DeleteVariableCmd implements Command<Program> {
private Variable var; private Variable var;
@ -35,6 +33,7 @@ public class DeleteVariableCmd implements Command {
* *
* @see ghidra.framework.cmd.Command#getName() * @see ghidra.framework.cmd.Command#getName()
*/ */
@Override
public String getName() { public String getName() {
return "Delete " + (var instanceof Parameter ? "Parameter" : "Variable"); return "Delete " + (var instanceof Parameter ? "Parameter" : "Variable");
} }
@ -43,17 +42,20 @@ public class DeleteVariableCmd implements Command {
* *
* @see ghidra.framework.cmd.Command#applyTo(ghidra.framework.model.DomainObject) * @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(); Function f = var.getFunction();
if (f == null || f.getProgram() != program) {
return false;
}
f.removeVariable(var); f.removeVariable(var);
return true; return true;
} }
/** /**
* @see ghidra.framework.cmd.Command#getStatusMsg() * @see ghidra.framework.cmd.Command#getStatusMsg()
*/ */
@Override
public String getStatusMsg() { public String getStatusMsg() {
return ""; return "";
} }

View file

@ -16,7 +16,6 @@
package ghidra.app.cmd.function; package ghidra.app.cmd.function;
import ghidra.framework.cmd.BackgroundCommand; import ghidra.framework.cmd.BackgroundCommand;
import ghidra.framework.model.DomainObject;
import ghidra.program.model.address.*; import ghidra.program.model.address.*;
import ghidra.program.model.lang.Processor; import ghidra.program.model.lang.Processor;
import ghidra.program.model.lang.PrototypeModel; 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. * Command for analyzing the Stack; the command is run in the background.
*/ */
public class FunctionPurgeAnalysisCmd extends BackgroundCommand { public class FunctionPurgeAnalysisCmd extends BackgroundCommand<Program> {
private AddressSetView entryPoints; private AddressSetView entryPoints;
private Program program; private Program program;
private PrototypeModel[] nearFarModels = null; private PrototypeModel[] nearFarModels = null;
@ -52,13 +51,9 @@ public class FunctionPurgeAnalysisCmd extends BackgroundCommand {
entryPoints = entries; entryPoints = entries;
} }
/**
*
* @see ghidra.framework.cmd.BackgroundCommand#applyTo(ghidra.framework.model.DomainObject, ghidra.util.task.TaskMonitor)
*/
@Override @Override
public boolean applyTo(DomainObject obj, TaskMonitor monitor) { public boolean applyTo(Program p, TaskMonitor monitor) {
program = (Program) obj; program = p;
Processor processor = program.getLanguage().getProcessor(); Processor processor = program.getLanguage().getProcessor();
AddressSpace defaultSpace = program.getLanguage().getDefaultSpace(); AddressSpace defaultSpace = program.getLanguage().getDefaultSpace();

View file

@ -18,7 +18,6 @@ package ghidra.app.cmd.function;
import java.util.*; import java.util.*;
import ghidra.framework.cmd.BackgroundCommand; import ghidra.framework.cmd.BackgroundCommand;
import ghidra.framework.model.DomainObject;
import ghidra.program.model.address.*; import ghidra.program.model.address.*;
import ghidra.program.model.data.DataType; import ghidra.program.model.data.DataType;
import ghidra.program.model.data.Undefined; import ghidra.program.model.data.Undefined;
@ -31,12 +30,11 @@ import ghidra.util.Msg;
import ghidra.util.exception.*; import ghidra.util.exception.*;
import ghidra.util.state.*; import ghidra.util.state.*;
import ghidra.util.task.TaskMonitor; import ghidra.util.task.TaskMonitor;
import ghidra.util.task.TaskMonitorAdapter;
/** /**
* Command for analyzing the Stack; the command is run in the background. * Command for analyzing the Stack; the command is run in the background.
*/ */
public class FunctionResultStateStackAnalysisCmd extends BackgroundCommand { public class FunctionResultStateStackAnalysisCmd extends BackgroundCommand<Program> {
private AddressSet entryPoints = new AddressSet(); private AddressSet entryPoints = new AddressSet();
private boolean forceProcessing = false; private boolean forceProcessing = false;
private boolean dontCreateNewVariables = false; private boolean dontCreateNewVariables = false;
@ -65,13 +63,8 @@ public class FunctionResultStateStackAnalysisCmd extends BackgroundCommand {
this(new AddressSet(entry, entry), forceProcessing); this(new AddressSet(entry, entry), forceProcessing);
} }
/**
*
* @see ghidra.framework.cmd.BackgroundCommand#applyTo(ghidra.framework.model.DomainObject, ghidra.util.task.TaskMonitor)
*/
@Override @Override
public boolean applyTo(DomainObject obj, TaskMonitor monitor) { public boolean applyTo(Program program, TaskMonitor monitor) {
Program program = (Program) obj;
int count = 0; int count = 0;
monitor.initialize(entryPoints.getNumAddresses()); monitor.initialize(entryPoints.getNumAddresses());
@ -335,13 +328,10 @@ public class FunctionResultStateStackAnalysisCmd extends BackgroundCommand {
for (SequenceNumber seq : results.getReturnAddresses()) { for (SequenceNumber seq : results.getReturnAddresses()) {
ContextState returnState = results.getContextStates(seq).next(); ContextState returnState = results.getContextStates(seq).next();
Varnode varnode = Varnode varnode =
returnState.get(results.getStackPointerVarnode(), returnState.get(results.getStackPointerVarnode(), TaskMonitor.DUMMY);
TaskMonitor.DUMMY); Varnode zero = new Varnode(addrFactory.getConstantSpace().getAddress(0),
Varnode zero =
new Varnode(addrFactory.getConstantSpace().getAddress(0),
stackReg.getMinimumByteSize()); stackReg.getMinimumByteSize());
varnode = varnode = replaceInputVarnodes(varnode, results.getStackPointerVarnode(), zero, 4,
replaceInputVarnodes(varnode, results.getStackPointerVarnode(), zero, 4,
monitor); monitor);
if (varnode == null) { if (varnode == null) {
continue; continue;

View file

@ -15,8 +15,10 @@
*/ */
package ghidra.app.cmd.function; package ghidra.app.cmd.function;
import java.util.ArrayList;
import java.util.Stack;
import ghidra.framework.cmd.BackgroundCommand; import ghidra.framework.cmd.BackgroundCommand;
import ghidra.framework.model.DomainObject;
import ghidra.program.model.address.*; import ghidra.program.model.address.*;
import ghidra.program.model.data.*; import ghidra.program.model.data.*;
import ghidra.program.model.lang.Register; import ghidra.program.model.lang.Register;
@ -28,14 +30,11 @@ import ghidra.util.Msg;
import ghidra.util.exception.*; import ghidra.util.exception.*;
import ghidra.util.task.TaskMonitor; 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. * Command for analyzing the Stack; the command is run in the background.
* NOTE: referenced thunk-functions should be created prior to this command * NOTE: referenced thunk-functions should be created prior to this command
*/ */
public class FunctionStackAnalysisCmd extends BackgroundCommand { public class FunctionStackAnalysisCmd extends BackgroundCommand<Program> {
private AddressSet entryPoints = new AddressSet(); private AddressSet entryPoints = new AddressSet();
private Program program; private Program program;
private boolean forceProcessing = false; private boolean forceProcessing = false;
@ -76,13 +75,9 @@ public class FunctionStackAnalysisCmd extends BackgroundCommand {
doLocals = doLocalAnalysis; doLocals = doLocalAnalysis;
} }
/**
*
* @see ghidra.framework.cmd.BackgroundCommand#applyTo(ghidra.framework.model.DomainObject, ghidra.util.task.TaskMonitor)
*/
@Override @Override
public boolean applyTo(DomainObject obj, TaskMonitor monitor) { public boolean applyTo(Program p, TaskMonitor monitor) {
program = (Program) obj; program = p;
int count = 0; int count = 0;
monitor.initialize(entryPoints.getNumAddresses()); monitor.initialize(entryPoints.getNumAddresses());
@ -285,7 +280,8 @@ public class FunctionStackAnalysisCmd extends BackgroundCommand {
// return true; // 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(); ReferenceManager refMgr = program.getReferenceManager();
@ -365,8 +361,7 @@ public class FunctionStackAnalysisCmd extends BackgroundCommand {
return null; return null;
} }
// only create variables at locations where a variable doesn't exist // only create variables at locations where a variable doesn't exist
var = var = frame.createVariable(null, frameLoc, Undefined.getUndefinedDataType(refSize),
frame.createVariable(null, frameLoc, Undefined.getUndefinedDataType(refSize),
SourceType.ANALYSIS); SourceType.ANALYSIS);
} }
catch (DuplicateNameException e) { catch (DuplicateNameException e) {

View file

@ -19,7 +19,6 @@ import java.math.BigInteger;
import java.util.*; import java.util.*;
import ghidra.framework.cmd.BackgroundCommand; import ghidra.framework.cmd.BackgroundCommand;
import ghidra.framework.model.DomainObject;
import ghidra.program.model.address.*; import ghidra.program.model.address.*;
import ghidra.program.model.data.DataType; import ghidra.program.model.data.DataType;
import ghidra.program.model.data.Undefined; 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. * Command for analyzing the Stack; the command is run in the background.
* NOTE: referenced thunk-functions should be created prior to this command * NOTE: referenced thunk-functions should be created prior to this command
*/ */
public class NewFunctionStackAnalysisCmd extends BackgroundCommand { public class NewFunctionStackAnalysisCmd extends BackgroundCommand<Program> {
private static final int MAX_PARAM_OFFSET = 2048; // max size of param reference space 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 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; doLocals = doLocalAnalysis;
} }
/**
*
* @see ghidra.framework.cmd.BackgroundCommand#applyTo(ghidra.framework.model.DomainObject, ghidra.util.task.TaskMonitor)
*/
@Override @Override
public boolean applyTo(DomainObject obj, TaskMonitor monitor) { public boolean applyTo(Program p, TaskMonitor monitor) {
program = (Program) obj; program = p;
int count = 0; int count = 0;
long numAddresses = entryPoints.getNumAddresses(); 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. * 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 * @param monitor the task monitor that is checked to see if the command has
* been cancelled. * been cancelled.
* @throws CancelledException if the user canceled this command * @throws CancelledException if the user canceled this command
@ -164,9 +159,8 @@ public class NewFunctionStackAnalysisCmd extends BackgroundCommand {
// Later this should change to stack locked. // Later this should change to stack locked.
Variable[] variables = func.getVariables(VariableFilter.STACK_VARIABLE_FILTER); Variable[] variables = func.getVariables(VariableFilter.STACK_VARIABLE_FILTER);
boolean hasReferences = false; boolean hasReferences = false;
for (int i = 0; i < variables.length; i++) { for (Variable variable : variables) {
Reference[] referencesTo = Reference[] referencesTo = program.getReferenceManager().getReferencesTo(variable);
program.getReferenceManager().getReferencesTo(variables[i]);
if (referencesTo.length != 0) { if (referencesTo.length != 0) {
hasReferences = true; hasReferences = true;
break; break;
@ -599,13 +593,13 @@ public class NewFunctionStackAnalysisCmd extends BackgroundCommand {
return -1; return -1;
} }
/** // /**
* Checks the indicated function in the program to determine if it is a jump thunk // * Checks the indicated function in the program to determine if it is a jump thunk
* through a function pointer. // * through a function pointer.
* @param func the function to check // * @param func the function to check
* @param monitor status monitor for indicating progress and allowing cancel. // * @param monitor status monitor for indicating progress and allowing cancel.
* @returntrue if check if this is a jump thunk through a function pointer // * @returntrue if check if this is a jump thunk through a function pointer
*/ // */
// private boolean checkThunk(Function func, TaskMonitor monitor) { // private boolean checkThunk(Function func, TaskMonitor monitor) {
// Instruction instr = program.getListing().getInstructionAt(func.getEntryPoint()); // Instruction instr = program.getListing().getInstructionAt(func.getEntryPoint());
// if (instr == null) { // if (instr == null) {

View file

@ -16,16 +16,13 @@
package ghidra.app.cmd.function; package ghidra.app.cmd.function;
import ghidra.framework.cmd.Command; 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.address.Address;
import ghidra.program.model.listing.Function; import ghidra.program.model.listing.*;
import ghidra.program.model.listing.FunctionManager;
/** /**
* Command for removing a tag from a function * Command for removing a tag from a function
*/ */
public class RemoveFunctionTagCmd implements Command { public class RemoveFunctionTagCmd implements Command<Program> {
private Address entryPoint; private Address entryPoint;
private String tagName; private String tagName;
@ -42,8 +39,7 @@ public class RemoveFunctionTagCmd implements Command {
} }
@Override @Override
public boolean applyTo(DomainObject obj) { public boolean applyTo(Program program) {
ProgramDB program = (ProgramDB) obj;
FunctionManager functionManager = program.getFunctionManager(); FunctionManager functionManager = program.getFunctionManager();
Function function = functionManager.getFunctionAt(entryPoint); Function function = functionManager.getFunctionAt(entryPoint);
function.removeTag(tagName); function.removeTag(tagName);

View file

@ -1,6 +1,5 @@
/* ### /* ###
* IP: GHIDRA * IP: GHIDRA
* REVIEWED: YES
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -17,28 +16,28 @@
package ghidra.app.cmd.function; package ghidra.app.cmd.function;
import ghidra.framework.cmd.Command; import ghidra.framework.cmd.Command;
import ghidra.framework.model.DomainObject;
import ghidra.program.model.address.Address; import ghidra.program.model.address.Address;
import ghidra.program.model.listing.Program; import ghidra.program.model.listing.Program;
public class RemoveStackDepthChangeCommand implements Command { public class RemoveStackDepthChangeCommand implements Command<Program> {
private Program program;
private Address address; private Address address;
public RemoveStackDepthChangeCommand(Program program, Address address) { public RemoveStackDepthChangeCommand(Address address) {
this.program = program;
this.address = address; this.address = address;
} }
public boolean applyTo(DomainObject obj) { @Override
public boolean applyTo(Program program) {
return CallDepthChangeInfo.removeStackDepthChange(program, address); return CallDepthChangeInfo.removeStackDepthChange(program, address);
} }
@Override
public String getName() { public String getName() {
return "Remove Stack Depth Change"; return "Remove Stack Depth Change";
} }
@Override
public String getStatusMsg() { public String getStatusMsg() {
return null; return null;
} }

View file

@ -1,6 +1,5 @@
/* ### /* ###
* IP: GHIDRA * IP: GHIDRA
* REVIEWED: YES
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -17,7 +16,6 @@
package ghidra.app.cmd.function; package ghidra.app.cmd.function;
import ghidra.framework.cmd.Command; import ghidra.framework.cmd.Command;
import ghidra.framework.model.DomainObject;
import ghidra.program.model.address.Address; import ghidra.program.model.address.Address;
import ghidra.program.model.listing.Function; import ghidra.program.model.listing.Function;
import ghidra.program.model.listing.Program; import ghidra.program.model.listing.Program;
@ -26,11 +24,12 @@ import ghidra.program.model.symbol.SourceType;
/** /**
* Command to set the name of a function. * Command to set the name of a function.
*/ */
public class SetFunctionNameCmd implements Command { public class SetFunctionNameCmd implements Command<Program> {
private Address entry; private Address entry;
private String name; private String name;
private String msg; private String msg;
private SourceType source; private SourceType source;
/** /**
* Constructs a new command for setting the name of a function. * Constructs a new command for setting the name of a function.
* @param entry the address of the function to be renamed. * @param entry the address of the function to be renamed.
@ -42,12 +41,9 @@ public class SetFunctionNameCmd implements Command {
this.name = newName; this.name = newName;
this.source = source; this.source = source;
} }
/**
* @Override
* @see ghidra.framework.cmd.Command#applyTo(ghidra.framework.model.DomainObject) public boolean applyTo(Program program) {
*/
public boolean applyTo(DomainObject obj) {
Program program = (Program)obj;
if (name.length() <= 0) { if (name.length() <= 0) {
name = null; name = null;
@ -68,18 +64,12 @@ public class SetFunctionNameCmd implements Command {
} }
/** @Override
*
* @see ghidra.framework.cmd.Command#getName()
*/
public String getName() { public String getName() {
return "Rename Function"; return "Rename Function";
} }
@Override
/**
* @see ghidra.framework.cmd.Command#getStatusMsg()
*/
public String getStatusMsg() { public String getStatusMsg() {
return msg; return msg;
} }

View file

@ -1,6 +1,5 @@
/* ### /* ###
* IP: GHIDRA * IP: GHIDRA
* REVIEWED: YES
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -17,8 +16,8 @@
package ghidra.app.cmd.function; package ghidra.app.cmd.function;
import ghidra.framework.cmd.Command; import ghidra.framework.cmd.Command;
import ghidra.framework.model.DomainObject;
import ghidra.program.model.listing.Function; import ghidra.program.model.listing.Function;
import ghidra.program.model.listing.Program;
/** /**
* A simple command to set the stack purge size of a function. * A simple command to set the stack purge size of a function.
@ -26,7 +25,7 @@ import ghidra.program.model.listing.Function;
* *
* @since Tracker Id 548 * @since Tracker Id 548
*/ */
public class SetFunctionPurgeCommand implements Command { public class SetFunctionPurgeCommand implements Command<Program> {
private Function function; private Function function;
private int functionPurge; private int functionPurge;
@ -42,24 +41,18 @@ public class SetFunctionPurgeCommand implements Command {
this.functionPurge = newPurge; this.functionPurge = newPurge;
} }
/** @Override
* @see ghidra.framework.cmd.Command#applyTo(ghidra.framework.model.DomainObject) public boolean applyTo(Program program) {
*/
public boolean applyTo(DomainObject obj) {
function.setStackPurgeSize(functionPurge); function.setStackPurgeSize(functionPurge);
return true; return true;
} }
/** @Override
* @see ghidra.framework.cmd.Command#getStatusMsg()
*/
public String getStatusMsg() { public String getStatusMsg() {
return ""; return "";
} }
/** @Override
* @see ghidra.framework.cmd.Command#getName()
*/
public String getName() { public String getName() {
return "Set Function Purge"; return "Set Function Purge";
} }

View file

@ -1,6 +1,5 @@
/* ### /* ###
* IP: GHIDRA * IP: GHIDRA
* REVIEWED: YES
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -17,7 +16,6 @@
package ghidra.app.cmd.function; package ghidra.app.cmd.function;
import ghidra.framework.cmd.Command; import ghidra.framework.cmd.Command;
import ghidra.framework.model.DomainObject;
import ghidra.program.model.address.Address; import ghidra.program.model.address.Address;
import ghidra.program.model.listing.Function; import ghidra.program.model.listing.Function;
import ghidra.program.model.listing.Program; import ghidra.program.model.listing.Program;
@ -25,7 +23,7 @@ import ghidra.program.model.listing.Program;
/** /**
* Command to set the Function's Repeatable Comment. * Command to set the Function's Repeatable Comment.
*/ */
public class SetFunctionRepeatableCommentCmd implements Command { public class SetFunctionRepeatableCommentCmd implements Command<Program> {
private Address entry; private Address entry;
private String newRepeatableComment; private String newRepeatableComment;
@ -39,20 +37,13 @@ public class SetFunctionRepeatableCommentCmd implements Command {
this.newRepeatableComment = newRepeatableComment; this.newRepeatableComment = newRepeatableComment;
} }
/** @Override
*
* @see ghidra.framework.cmd.Command#getName()
*/
public String getName() { public String getName() {
return "Set Function Repeatable Comment"; return "Set Function Repeatable Comment";
} }
/** @Override
* public boolean applyTo(Program program) {
* @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); Function f = program.getListing().getFunctionAt(entry);
if (f != null) { if (f != null) {
f.setRepeatableComment(newRepeatableComment); f.setRepeatableComment(newRepeatableComment);
@ -60,9 +51,7 @@ public class SetFunctionRepeatableCommentCmd implements Command {
return true; return true;
} }
/** @Override
* @see ghidra.framework.cmd.Command#getStatusMsg()
*/
public String getStatusMsg() { public String getStatusMsg() {
return ""; return "";
} }

View file

@ -1,6 +1,5 @@
/* ### /* ###
* IP: GHIDRA * IP: GHIDRA
* REVIEWED: YES
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -17,13 +16,13 @@
package ghidra.app.cmd.function; package ghidra.app.cmd.function;
import ghidra.framework.cmd.Command; import ghidra.framework.cmd.Command;
import ghidra.framework.model.DomainObject;
import ghidra.program.model.listing.Function; import ghidra.program.model.listing.Function;
import ghidra.program.model.listing.Program;
/** /**
* A simple command to set whether or not a function has VarArgs. * A simple command to set whether or not a function has VarArgs.
*/ */
public class SetFunctionVarArgsCommand implements Command { public class SetFunctionVarArgsCommand implements Command<Program> {
private Function function; private Function function;
private boolean hasVarArgs; private boolean hasVarArgs;
@ -39,24 +38,18 @@ public class SetFunctionVarArgsCommand implements Command {
this.hasVarArgs = hasVarArgs; this.hasVarArgs = hasVarArgs;
} }
/** @Override
* @see ghidra.framework.cmd.Command#applyTo(ghidra.framework.model.DomainObject) public boolean applyTo(Program program) {
*/
public boolean applyTo(DomainObject obj) {
function.setVarArgs(hasVarArgs); function.setVarArgs(hasVarArgs);
return true; return true;
} }
/** @Override
* @see ghidra.framework.cmd.Command#getStatusMsg()
*/
public String getStatusMsg() { public String getStatusMsg() {
return ""; return "";
} }
/** @Override
* @see ghidra.framework.cmd.Command#getName()
*/
public String getName() { public String getName() {
return "Set Function VarArgs"; return "Set Function VarArgs";
} }

View file

@ -1,6 +1,5 @@
/* ### /* ###
* IP: GHIDRA * IP: GHIDRA
* REVIEWED: YES
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -17,7 +16,6 @@
package ghidra.app.cmd.function; package ghidra.app.cmd.function;
import ghidra.framework.cmd.Command; import ghidra.framework.cmd.Command;
import ghidra.framework.model.DomainObject;
import ghidra.program.model.address.Address; import ghidra.program.model.address.Address;
import ghidra.program.model.data.DataType; import ghidra.program.model.data.DataType;
import ghidra.program.model.listing.Function; import ghidra.program.model.listing.Function;
@ -28,7 +26,7 @@ import ghidra.util.exception.InvalidInputException;
/** /**
* Command for setting a function's return type. * Command for setting a function's return type.
*/ */
public class SetReturnDataTypeCmd implements Command { public class SetReturnDataTypeCmd implements Command<Program> {
private Address entry; private Address entry;
private DataType dataType; private DataType dataType;
private String status; private String status;
@ -46,22 +44,13 @@ public class SetReturnDataTypeCmd implements Command {
this.source = source; this.source = source;
} }
/**
*
* @see ghidra.framework.cmd.Command#getName()
*/
@Override @Override
public String getName() { public String getName() {
return "Set Return Data Type"; return "Set Return Data Type";
} }
/**
*
* @see ghidra.framework.cmd.Command#applyTo(ghidra.framework.model.DomainObject)
*/
@Override @Override
public boolean applyTo(DomainObject obj) { public boolean applyTo(Program program) {
Program program = (Program) obj;
Function function = program.getListing().getFunctionAt(entry); Function function = program.getListing().getFunctionAt(entry);
try { try {
function.setReturnType(dataType, source); function.setReturnType(dataType, source);
@ -76,9 +65,6 @@ public class SetReturnDataTypeCmd implements Command {
return true; return true;
} }
/**
* @see ghidra.framework.cmd.Command#getStatusMsg()
*/
@Override @Override
public String getStatusMsg() { public String getStatusMsg() {
return status; return status;

View file

@ -1,6 +1,5 @@
/* ### /* ###
* IP: GHIDRA * IP: GHIDRA
* REVIEWED: YES
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -17,40 +16,41 @@
package ghidra.app.cmd.function; package ghidra.app.cmd.function;
import ghidra.framework.cmd.Command; import ghidra.framework.cmd.Command;
import ghidra.framework.model.DomainObject;
import ghidra.program.model.address.Address; import ghidra.program.model.address.Address;
import ghidra.program.model.listing.Program; import ghidra.program.model.listing.Program;
import ghidra.util.Msg; import ghidra.util.Msg;
import ghidra.util.exception.DuplicateNameException; import ghidra.util.exception.DuplicateNameException;
public class SetStackDepthChangeCommand implements Command { public class SetStackDepthChangeCommand implements Command<Program> {
private Program program;
private Address address; private Address address;
private int stackDepthChange; private int stackDepthChange;
private String errMsg = null; private String errMsg = null;
public SetStackDepthChangeCommand(Program program, Address address, int newStackDepthChange) { public SetStackDepthChangeCommand(Address address, int newStackDepthChange) {
this.program = program;
this.address = address; this.address = address;
this.stackDepthChange = newStackDepthChange; this.stackDepthChange = newStackDepthChange;
} }
public boolean applyTo(DomainObject obj) { @Override
public boolean applyTo(Program program) {
try { try {
CallDepthChangeInfo.setStackDepthChange(program, address, stackDepthChange); CallDepthChangeInfo.setStackDepthChange(program, address, stackDepthChange);
return true; return true;
} catch (DuplicateNameException e) { }
catch (DuplicateNameException e) {
errMsg = e.getMessage(); errMsg = e.getMessage();
Msg.error(this, "Unexpected Exception: " + e.getMessage(), e); Msg.error(this, "Unexpected Exception: " + e.getMessage(), e);
return false; return false;
} }
} }
@Override
public String getName() { public String getName() {
return "Set Stack Depth Change"; return "Set Stack Depth Change";
} }
@Override
public String getStatusMsg() { public String getStatusMsg() {
return errMsg; return errMsg;
} }

View file

@ -1,6 +1,5 @@
/* ### /* ###
* IP: GHIDRA * IP: GHIDRA
* REVIEWED: YES
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -17,14 +16,13 @@
package ghidra.app.cmd.function; package ghidra.app.cmd.function;
import ghidra.framework.cmd.Command; import ghidra.framework.cmd.Command;
import ghidra.framework.model.DomainObject; import ghidra.program.model.listing.Program;
import ghidra.program.model.listing.Variable; import ghidra.program.model.listing.Variable;
/** /**
* Command to set the comment on a function varible. * Command to set the comment on a function varible.
*/ */
public class SetVariableCommentCmd implements Command { public class SetVariableCommentCmd implements Command<Program> {
private Variable var; private Variable var;
private String comment; private String comment;
private String msg; private String msg;
@ -39,27 +37,18 @@ public class SetVariableCommentCmd implements Command {
this.comment = newComment; this.comment = newComment;
} }
/** @Override
*
* @see ghidra.framework.cmd.Command#getName()
*/
public String getName() { public String getName() {
return "Set Variable Comment"; return "Set Variable Comment";
} }
/** @Override
* public boolean applyTo(Program program) {
* @see ghidra.framework.cmd.Command#applyTo(ghidra.framework.model.DomainObject)
*/
public boolean applyTo(DomainObject obj) {
var.setComment(comment); var.setComment(comment);
return true; return true;
} }
@Override
/**
* @see ghidra.framework.cmd.Command#getStatusMsg()
*/
public String getStatusMsg() { public String getStatusMsg() {
return msg; return msg;
} }

View file

@ -16,7 +16,6 @@
package ghidra.app.cmd.function; package ghidra.app.cmd.function;
import ghidra.framework.cmd.Command; import ghidra.framework.cmd.Command;
import ghidra.framework.model.DomainObject;
import ghidra.program.model.address.Address; import ghidra.program.model.address.Address;
import ghidra.program.model.data.*; import ghidra.program.model.data.*;
import ghidra.program.model.listing.*; import ghidra.program.model.listing.*;
@ -27,7 +26,7 @@ import ghidra.util.exception.InvalidInputException;
/** /**
* Command to set the datatype on a stack variable. * Command to set the datatype on a stack variable.
*/ */
public class SetVariableDataTypeCmd implements Command { public class SetVariableDataTypeCmd implements Command<Program> {
private final Address fnEntry; private final Address fnEntry;
private final String varName; private final String varName;
@ -86,10 +85,6 @@ public class SetVariableDataTypeCmd implements Command {
this.source = source; this.source = source;
} }
/**
*
* @see ghidra.framework.cmd.Command#getName()
*/
@Override @Override
public String getName() { public String getName() {
return "Set " + (isParm ? "Parameter" : "Variable") + " Data Type"; 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) * @see ghidra.framework.cmd.Command#applyTo(ghidra.framework.model.DomainObject)
*/ */
@Override @Override
public boolean applyTo(DomainObject obj) { public boolean applyTo(Program program) {
if (!(obj instanceof Program)) { Function f = program.getFunctionManager().getFunctionAt(fnEntry);
return false;
}
Program p = (Program) obj;
Function f = p.getFunctionManager().getFunctionAt(fnEntry);
if (f == null) { if (f == null) {
status = "Function not found"; status = "Function not found";
return false; return false;
} }
Symbol s = p.getSymbolTable().getParameterSymbol(varName, f); Symbol s = program.getSymbolTable().getParameterSymbol(varName, f);
if (s == null) { if (s == null) {
s = p.getSymbolTable().getLocalVariableSymbol(varName, f); s = program.getSymbolTable().getLocalVariableSymbol(varName, f);
} }
if (s == null) { if (s == null) {
status = "Variable not found"; status = "Variable not found";

View file

@ -16,7 +16,6 @@
package ghidra.app.cmd.function; package ghidra.app.cmd.function;
import ghidra.framework.cmd.Command; import ghidra.framework.cmd.Command;
import ghidra.framework.model.DomainObject;
import ghidra.program.model.address.Address; import ghidra.program.model.address.Address;
import ghidra.program.model.listing.*; import ghidra.program.model.listing.*;
import ghidra.program.model.symbol.SourceType; import ghidra.program.model.symbol.SourceType;
@ -27,7 +26,7 @@ import ghidra.util.exception.InvalidInputException;
/** /**
* Command to rename a stack variable. * Command to rename a stack variable.
*/ */
public class SetVariableNameCmd implements Command { public class SetVariableNameCmd implements Command<Program> {
private Address fnEntry; private Address fnEntry;
private String varName; private String varName;
@ -64,27 +63,18 @@ public class SetVariableNameCmd implements Command {
this.source = source; this.source = source;
} }
/**
*
* @see ghidra.framework.cmd.Command#applyTo(ghidra.framework.model.DomainObject)
*/
@Override @Override
public boolean applyTo(DomainObject obj) { public boolean applyTo(Program program) {
if (!(obj instanceof Program)) { Function f = program.getFunctionManager().getFunctionAt(fnEntry);
return false;
}
Program p = (Program) obj;
Function f = p.getFunctionManager().getFunctionAt(fnEntry);
if (f == null) { if (f == null) {
status = "Function not found"; status = "Function not found";
return false; return false;
} }
Symbol s = p.getSymbolTable().getParameterSymbol(varName, f); Symbol s = program.getSymbolTable().getParameterSymbol(varName, f);
if (s == null) { if (s == null) {
s = p.getSymbolTable().getLocalVariableSymbol(varName, f); s = program.getSymbolTable().getLocalVariableSymbol(varName, f);
} }
if (s == null) { if (s == null) {
status = "Variable not found"; status = "Variable not found";
@ -106,17 +96,11 @@ public class SetVariableNameCmd implements Command {
return false; return false;
} }
/**
* @see ghidra.framework.cmd.Command#getStatusMsg()
*/
@Override @Override
public String getStatusMsg() { public String getStatusMsg() {
return status; return status;
} }
/**
* @see ghidra.framework.cmd.Command#getName()
*/
@Override @Override
public String getName() { public String getName() {
return "Rename " + (isParm ? "Parameter" : "Variable"); return "Rename " + (isParm ? "Parameter" : "Variable");

View file

@ -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<Program> {
private final Function function;
private final FunctionUpdateType updateType;
private final String callingConvention;
private final Variable returnVar;
private final List<? extends Variable> 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<? extends Variable> 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";
}
}

View file

@ -16,7 +16,6 @@
package ghidra.app.cmd.label; package ghidra.app.cmd.label;
import ghidra.framework.cmd.Command; import ghidra.framework.cmd.Command;
import ghidra.framework.model.DomainObject;
import ghidra.program.model.address.Address; import ghidra.program.model.address.Address;
import ghidra.program.model.listing.Program; import ghidra.program.model.listing.Program;
import ghidra.program.model.symbol.*; import ghidra.program.model.symbol.*;
@ -25,7 +24,7 @@ import ghidra.util.exception.InvalidInputException;
/** /**
* Command to add a label. * Command to add a label.
*/ */
public class AddLabelCmd implements Command { public class AddLabelCmd implements Command<Program> {
private Address addr; private Address addr;
private String name; private String name;
private Namespace namespace; private Namespace namespace;
@ -76,13 +75,9 @@ public class AddLabelCmd implements Command {
this(addr, name, null, source); this(addr, name, null, source);
} }
/**
*
* @see ghidra.framework.cmd.Command#applyTo(ghidra.framework.model.DomainObject)
*/
@Override @Override
public boolean applyTo(DomainObject obj) { public boolean applyTo(Program program) {
SymbolTable st = ((Program) obj).getSymbolTable(); SymbolTable st = program.getSymbolTable();
if (namespace == null && useLocalNamespace) { if (namespace == null && useLocalNamespace) {
namespace = st.getNamespace(addr); namespace = st.getNamespace(addr);
} }
@ -103,17 +98,11 @@ public class AddLabelCmd implements Command {
} }
/**
* @see ghidra.framework.cmd.Command#getStatusMsg()
*/
@Override @Override
public String getStatusMsg() { public String getStatusMsg() {
return errorMsg; return errorMsg;
} }
/**
* @see ghidra.framework.cmd.Command#getName()
*/
@Override @Override
public String getName() { public String getName() {
return "Add Label"; return "Add Label";

View file

@ -16,7 +16,6 @@
package ghidra.app.cmd.label; package ghidra.app.cmd.label;
import ghidra.framework.cmd.Command; import ghidra.framework.cmd.Command;
import ghidra.framework.model.DomainObject;
import ghidra.program.model.address.Address; import ghidra.program.model.address.Address;
import ghidra.program.model.listing.Program; import ghidra.program.model.listing.Program;
import ghidra.program.model.symbol.*; 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 The need for this class is now unnecessary since duplicate labels are permitted
*/ */
@Deprecated @Deprecated
public class AddUniqueLabelCmd implements Command { public class AddUniqueLabelCmd implements Command<Program> {
private Address address; private Address address;
private String name; private String name;
private Namespace namespace; private Namespace namespace;
@ -52,12 +51,9 @@ public class AddUniqueLabelCmd implements Command {
this.source = source; this.source = source;
} }
/**
* @see ghidra.framework.cmd.Command#applyTo(ghidra.framework.model.DomainObject)
*/
@Override @Override
public boolean applyTo(DomainObject obj) { public boolean applyTo(Program program) {
SymbolTable symbolTable = ((Program) obj).getSymbolTable(); SymbolTable symbolTable = program.getSymbolTable();
try { try {
newSymbol = symbolTable.createLabel(address, name, namespace, source); newSymbol = symbolTable.createLabel(address, name, namespace, source);
return true;//symbol already exist at this address, just complete return true;//symbol already exist at this address, just complete
@ -76,17 +72,11 @@ public class AddUniqueLabelCmd implements Command {
return false; return false;
} }
/**
* @see ghidra.framework.cmd.Command#getStatusMsg()
*/
@Override @Override
public String getStatusMsg() { public String getStatusMsg() {
return errorMsg; return errorMsg;
} }
/**
* @see ghidra.framework.cmd.Command#getName()
*/
@Override @Override
public String getName() { public String getName() {
return "Add Unique Label"; return "Add Unique Label";

View file

@ -17,7 +17,6 @@ package ghidra.app.cmd.label;
import ghidra.app.util.NamespaceUtils; import ghidra.app.util.NamespaceUtils;
import ghidra.framework.cmd.Command; import ghidra.framework.cmd.Command;
import ghidra.framework.model.DomainObject;
import ghidra.program.model.listing.Program; import ghidra.program.model.listing.Program;
import ghidra.program.model.symbol.Namespace; import ghidra.program.model.symbol.Namespace;
import ghidra.program.model.symbol.SourceType; import ghidra.program.model.symbol.SourceType;
@ -43,7 +42,7 @@ import ghidra.util.exception.InvalidInputException;
* @since Tracker Id 619 * @since Tracker Id 619
* @see NamespaceUtils * @see NamespaceUtils
*/ */
public class CreateNamespacesCmd implements Command { public class CreateNamespacesCmd implements Command<Program> {
private String statusMsg; private String statusMsg;
@ -83,11 +82,12 @@ public class CreateNamespacesCmd implements Command {
* @see <a href="#examples">example format</a> * @see <a href="#examples">example format</a>
* @see <a href="#assumptions">assumptions</a> * @see <a href="#assumptions">assumptions</a>
*/ */
public CreateNamespacesCmd(String namespacesString, Namespace parentNamespace, SourceType source) { public CreateNamespacesCmd(String namespacesString, Namespace parentNamespace,
SourceType source) {
if (namespacesString == null) { if (namespacesString == null) {
throw new NullPointerException("Cannot create namespaces from a " throw new NullPointerException(
+ "null namespacesString value."); "Cannot create namespaces from a " + "null namespacesString value.");
} }
this.namespacesString = namespacesString; this.namespacesString = namespacesString;
@ -95,16 +95,12 @@ public class CreateNamespacesCmd implements Command {
this.source = source; this.source = source;
} }
/**
* @see ghidra.framework.cmd.Command#applyTo(ghidra.framework.model.DomainObject)
*/
@Override @Override
public boolean applyTo(DomainObject obj) { public boolean applyTo(Program program) {
try { try {
leafNamespace = leafNamespace = NamespaceUtils.createNamespaceHierarchy(namespacesString, rootNamespace,
NamespaceUtils.createNamespaceHierarchy(namespacesString, rootNamespace, program, source);
(Program) obj, source);
if (leafNamespace != null) { if (leafNamespace != null) {
return true; return true;

View file

@ -1,6 +1,5 @@
/* ### /* ###
* IP: GHIDRA * IP: GHIDRA
* REVIEWED: YES
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -17,7 +16,6 @@
package ghidra.app.cmd.label; package ghidra.app.cmd.label;
import ghidra.framework.cmd.Command; import ghidra.framework.cmd.Command;
import ghidra.framework.model.DomainObject;
import ghidra.program.model.address.Address; import ghidra.program.model.address.Address;
import ghidra.program.model.listing.Program; import ghidra.program.model.listing.Program;
import ghidra.program.model.symbol.*; import ghidra.program.model.symbol.*;
@ -25,7 +23,7 @@ import ghidra.program.model.symbol.*;
/** /**
* Command to delete a label * Command to delete a label
*/ */
public class DeleteLabelCmd implements Command { public class DeleteLabelCmd implements Command<Program> {
private Address addr; private Address addr;
private String name; private String name;
@ -54,13 +52,9 @@ public class DeleteLabelCmd implements Command {
this(addr, name, null); this(addr, name, null);
} }
/**
*
* @see ghidra.framework.cmd.Command#applyTo(ghidra.framework.model.DomainObject)
*/
@Override @Override
public boolean applyTo(DomainObject obj) { public boolean applyTo(Program program) {
SymbolTable st = ((Program) obj).getSymbolTable(); SymbolTable st = program.getSymbolTable();
Symbol s = st.getSymbol(name, addr, scope); Symbol s = st.getSymbol(name, addr, scope);
if (s == null) { if (s == null) {
errorMsg = "Symbol " + name + " not found!"; errorMsg = "Symbol " + name + " not found!";
@ -74,7 +68,7 @@ public class DeleteLabelCmd implements Command {
if (s.isExternalEntryPoint() && s.isPrimary()) { if (s.isExternalEntryPoint() && s.isPrimary()) {
if (st.getSymbols(s.getAddress()).length == 1) { if (st.getSymbols(s.getAddress()).length == 1) {
externalEntryCmd = new ExternalEntryCmd(addr, false); externalEntryCmd = new ExternalEntryCmd(addr, false);
externalEntryCmd.applyTo(obj); externalEntryCmd.applyTo(program);
} }
} }
boolean success = st.removeSymbolSpecial(s); boolean success = st.removeSymbolSpecial(s);
@ -84,17 +78,11 @@ public class DeleteLabelCmd implements Command {
return success; return success;
} }
/**
* @see ghidra.framework.cmd.Command#getName()
*/
@Override @Override
public String getName() { public String getName() {
return "Delete Label"; return "Delete Label";
} }
/**
* @see ghidra.framework.cmd.Command#getStatusMsg()
*/
@Override @Override
public String getStatusMsg() { public String getStatusMsg() {
return errorMsg; return errorMsg;

View file

@ -19,7 +19,6 @@ import java.util.List;
import ghidra.app.util.demangler.*; import ghidra.app.util.demangler.*;
import ghidra.framework.cmd.BackgroundCommand; import ghidra.framework.cmd.BackgroundCommand;
import ghidra.framework.model.DomainObject;
import ghidra.program.model.address.Address; import ghidra.program.model.address.Address;
import ghidra.program.model.listing.Program; import ghidra.program.model.listing.Program;
import ghidra.program.model.symbol.SymbolUtilities; import ghidra.program.model.symbol.SymbolUtilities;
@ -27,7 +26,7 @@ import ghidra.util.Msg;
import ghidra.util.classfinder.ClassSearcher; import ghidra.util.classfinder.ClassSearcher;
import ghidra.util.task.TaskMonitor; import ghidra.util.task.TaskMonitor;
public class DemanglerCmd extends BackgroundCommand { public class DemanglerCmd extends BackgroundCommand<Program> {
private Address addr; private Address addr;
private String mangled; private String mangled;
@ -49,10 +48,9 @@ public class DemanglerCmd extends BackgroundCommand {
} }
@Override @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 // search until we find a demangler that can handle the given mangled input
Program prog = (Program) obj;
for (Demangler demangler : getDemanglers()) { for (Demangler demangler : getDemanglers()) {
if (!demangler.canDemangle(prog)) { if (!demangler.canDemangle(prog)) {
continue; continue;
@ -114,8 +112,7 @@ public class DemanglerCmd extends BackgroundCommand {
return false; return false;
} }
setStatusMsg( setStatusMsg("Failed to apply mangled symbol at " + addr + "; name: " + mangled + " (" +
"Failed to apply mangled symbol at " + addr + "; name: " + mangled + " (" +
demangler.getClass().getName() + "/" + demangledObject.getClass().getName() + ")"); demangler.getClass().getName() + "/" + demangledObject.getClass().getName() + ")");
return false; // error return false; // error
} }

View file

@ -1,6 +1,5 @@
/* ### /* ###
* IP: GHIDRA * IP: GHIDRA
* REVIEWED: YES
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -17,7 +16,6 @@
package ghidra.app.cmd.label; package ghidra.app.cmd.label;
import ghidra.framework.cmd.Command; import ghidra.framework.cmd.Command;
import ghidra.framework.model.DomainObject;
import ghidra.program.model.address.Address; import ghidra.program.model.address.Address;
import ghidra.program.model.listing.Program; import ghidra.program.model.listing.Program;
import ghidra.program.model.symbol.SymbolTable; import ghidra.program.model.symbol.SymbolTable;
@ -25,12 +23,11 @@ import ghidra.program.model.symbol.SymbolTable;
/** /**
* Command for setting/unsetting an external entry point. * Command for setting/unsetting an external entry point.
*/ */
public class ExternalEntryCmd implements Command { public class ExternalEntryCmd implements Command<Program> {
private SymbolTable st;
private Address addr; private Address addr;
private boolean isEntry; private boolean isEntry;
/** /**
* Construct a new command for setting/unsetting an external entry point * Construct a new command for setting/unsetting an external entry point
* @param addr address to set or unset as 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; this.isEntry = isEntry;
} }
/** @Override
* public boolean applyTo(Program program) {
* @see ghidra.framework.cmd.Command#applyTo(ghidra.framework.model.DomainObject) SymbolTable st = program.getSymbolTable();
*/
public boolean applyTo(DomainObject obj) {
st = ((Program)obj).getSymbolTable();
if (isEntry) { if (isEntry) {
st.addExternalEntryPoint(addr); st.addExternalEntryPoint(addr);
} }
@ -57,18 +50,12 @@ public class ExternalEntryCmd implements Command {
return true; return true;
} }
@Override
/**
* @see ghidra.framework.cmd.Command#getName()
*/
public String getName() { public String getName() {
return "Set External" + isEntry; return "Set External" + isEntry;
} }
/** @Override
* @see ghidra.framework.cmd.Command#getStatusMsg()
*/
public String getStatusMsg() { public String getStatusMsg() {
return ""; return "";
} }

View file

@ -16,13 +16,12 @@
package ghidra.app.cmd.label; package ghidra.app.cmd.label;
import ghidra.framework.cmd.Command; import ghidra.framework.cmd.Command;
import ghidra.framework.model.DomainObject;
import ghidra.program.model.address.Address; import ghidra.program.model.address.Address;
import ghidra.program.model.listing.Program; import ghidra.program.model.listing.Program;
import ghidra.program.model.symbol.Symbol; import ghidra.program.model.symbol.Symbol;
import ghidra.program.model.symbol.SymbolTable; import ghidra.program.model.symbol.SymbolTable;
public class PinSymbolCmd implements Command { public class PinSymbolCmd implements Command<Program> {
private Address addr; private Address addr;
private String name; private String name;
@ -36,8 +35,8 @@ public class PinSymbolCmd implements Command {
} }
@Override @Override
public boolean applyTo(DomainObject obj) { public boolean applyTo(Program program) {
SymbolTable symbolTable = ((Program) obj).getSymbolTable(); SymbolTable symbolTable = program.getSymbolTable();
Symbol symbol = symbolTable.getGlobalSymbol(name, addr); Symbol symbol = symbolTable.getGlobalSymbol(name, addr);
if (symbol == null) { if (symbol == null) {
message = "Could not find symbol named " + name + " at address " + addr; message = "Could not find symbol named " + name + " at address " + addr;

View file

@ -22,7 +22,6 @@ import org.apache.commons.lang3.StringUtils;
import ghidra.app.util.NamespaceUtils; import ghidra.app.util.NamespaceUtils;
import ghidra.app.util.SymbolPath; import ghidra.app.util.SymbolPath;
import ghidra.framework.cmd.Command; import ghidra.framework.cmd.Command;
import ghidra.framework.model.DomainObject;
import ghidra.program.model.address.Address; import ghidra.program.model.address.Address;
import ghidra.program.model.listing.CircularDependencyException; import ghidra.program.model.listing.CircularDependencyException;
import ghidra.program.model.listing.Program; 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 * Command for renaming labels. Handles converting back and forth between default and named labels
* as well. * as well.
*/ */
public class RenameLabelCmd implements Command { public class RenameLabelCmd implements Command<Program> {
private Address addr; private Address addr;
private String oldName; private String oldName;
@ -123,9 +122,8 @@ public class RenameLabelCmd implements Command {
} }
@Override @Override
public boolean applyTo(DomainObject obj) { public boolean applyTo(Program program) {
Program program = (Program) obj;
if (currentNamespace == null) { if (currentNamespace == null) {
currentNamespace = program.getGlobalNamespace(); currentNamespace = program.getGlobalNamespace();
} }

View file

@ -1,6 +1,5 @@
/* ### /* ###
* IP: GHIDRA * IP: GHIDRA
* REVIEWED: YES
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -17,23 +16,19 @@
package ghidra.app.cmd.label; package ghidra.app.cmd.label;
import ghidra.framework.cmd.Command; import ghidra.framework.cmd.Command;
import ghidra.framework.model.DomainObject;
import ghidra.program.model.address.Address; import ghidra.program.model.address.Address;
import ghidra.program.model.listing.CircularDependencyException; import ghidra.program.model.listing.CircularDependencyException;
import ghidra.program.model.listing.Program; import ghidra.program.model.listing.Program;
import ghidra.program.model.symbol.*; 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.DuplicateNameException;
import ghidra.util.exception.InvalidInputException; import ghidra.util.exception.InvalidInputException;
/** /**
* Command for changing the scope of a label. * Command for changing the scope of a label.
* The scope is the namespace that the label is associated with. * The scope is the namespace that the label is associated with.
*/ */
public class SetLabelNamespaceCmd implements Command { public class SetLabelNamespaceCmd implements Command<Program> {
private SymbolTable st;
private Address addr; private Address addr;
private String name; private String name;
private Namespace oldNamespace; private Namespace oldNamespace;
@ -47,51 +42,46 @@ public class SetLabelNamespaceCmd implements Command {
* @param oldNamespace the current scope of the label that will be changed. * @param oldNamespace the current scope of the label that will be changed.
* @param newNamespace the new scope of the label. * @param newNamespace the new scope of the label.
*/ */
public SetLabelNamespaceCmd(Address addr, String name, public SetLabelNamespaceCmd(Address addr, String name, Namespace oldNamespace,
Namespace oldNamespace, Namespace newNamespace) { Namespace newNamespace) {
this.addr = addr; this.addr = addr;
this.name = name; this.name = name;
this.oldNamespace = oldNamespace; this.oldNamespace = oldNamespace;
this.newNamespace = newNamespace; this.newNamespace = newNamespace;
} }
/** @Override
* public boolean applyTo(Program program) {
* @see ghidra.framework.cmd.Command#applyTo(ghidra.framework.model.DomainObject) SymbolTable st = program.getSymbolTable();
*/
public boolean applyTo(DomainObject obj) {
st = ((Program)obj).getSymbolTable();
Symbol s = st.getSymbol(name, addr, oldNamespace); Symbol s = st.getSymbol(name, addr, oldNamespace);
if (s == null) { if (s == null) {
errorMsg = "No symbol named "+name+" found at address "+addr+ errorMsg = "No symbol named " + name + " found at address " + addr + " in namespace " +
" in namespace "+oldNamespace; oldNamespace;
return false; return false;
} }
try { try {
s.setNamespace(newNamespace); s.setNamespace(newNamespace);
return true; return true;
}catch (DuplicateNameException e) { }
catch (DuplicateNameException e) {
errorMsg = "Symbol named " + name + " already exists in namespace " + newNamespace; errorMsg = "Symbol named " + name + " already exists in namespace " + newNamespace;
} catch (InvalidInputException e) { }
catch (InvalidInputException e) {
errorMsg = e.getMessage(); errorMsg = e.getMessage();
} catch (CircularDependencyException e) { }
catch (CircularDependencyException e) {
errorMsg = e.getMessage(); errorMsg = e.getMessage();
} }
return false; return false;
} }
@Override
/**
* @see ghidra.framework.cmd.Command#getName()
*/
public String getName() { public String getName() {
return "Set Namespace"; return "Set Namespace";
} }
/** @Override
* @see ghidra.framework.cmd.Command#getStatusMsg()
*/
public String getStatusMsg() { public String getStatusMsg() {
return errorMsg; return errorMsg;
} }

View file

@ -16,7 +16,6 @@
package ghidra.app.cmd.label; package ghidra.app.cmd.label;
import ghidra.framework.cmd.Command; import ghidra.framework.cmd.Command;
import ghidra.framework.model.DomainObject;
import ghidra.program.model.address.Address; import ghidra.program.model.address.Address;
import ghidra.program.model.listing.CircularDependencyException; import ghidra.program.model.listing.CircularDependencyException;
import ghidra.program.model.listing.Program; 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 * makes sense if there is more than one label at the address - otherwise
* the label will already be primary. * the label will already be primary.
*/ */
public class SetLabelPrimaryCmd implements Command { public class SetLabelPrimaryCmd implements Command<Program> {
private SymbolTable st;
private Address addr; private Address addr;
private String name; private String name;
private Namespace namespace; private Namespace namespace;
@ -50,14 +49,9 @@ public class SetLabelPrimaryCmd implements Command {
this.namespace = namespace; this.namespace = namespace;
} }
/**
*
* @see ghidra.framework.cmd.Command#applyTo(ghidra.framework.model.DomainObject)
*/
@Override @Override
public boolean applyTo(DomainObject obj) { public boolean applyTo(Program program) {
Program program = (Program) obj; SymbolTable st = program.getSymbolTable();
st = program.getSymbolTable();
Symbol oldSymbol = st.getPrimarySymbol(addr); Symbol oldSymbol = st.getPrimarySymbol(addr);
if (oldSymbol == null) { 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, // change the state of the symbol, like changing the namespace of a default symbol,
// which has no effect // which has no effect
if (!oldSymbol.isDynamic()) { if (!oldSymbol.isDynamic()) {
errorMsg = errorMsg = "Symbol " + name + " does not exist in namespace " + namespace +
"Symbol " + name + " does not exist in namespace " + namespace + " at address " + addr;
" at address " +
addr;
return false; return false;
} }
return true; return true;
@ -103,7 +95,8 @@ public class SetLabelPrimaryCmd implements Command {
oldSymbol.setNameAndNamespace(name, namespace, symbolSource); oldSymbol.setNameAndNamespace(name, namespace, symbolSource);
symbol = oldSymbol; symbol = oldSymbol;
// If renamed oldSymbol is now Default source don't keep old name (handles special Thunk rename case) // 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 // put the other symbol back using the old namespace and old source
st.createLabel(addr, oldName, oldParent, oldSource); st.createLabel(addr, oldName, oldParent, oldSource);
} }
@ -127,17 +120,11 @@ public class SetLabelPrimaryCmd implements Command {
return true; return true;
} }
/**
* @see ghidra.framework.cmd.Command#getStatusMsg()
*/
@Override @Override
public String getStatusMsg() { public String getStatusMsg() {
return errorMsg; return errorMsg;
} }
/**
* @see ghidra.framework.cmd.Command#getName()
*/
@Override @Override
public String getName() { public String getName() {
return "Set Primary Label"; return "Set Primary Label";

View file

@ -16,7 +16,6 @@
package ghidra.app.cmd.memory; package ghidra.app.cmd.memory;
import ghidra.framework.cmd.Command; import ghidra.framework.cmd.Command;
import ghidra.framework.model.DomainObject;
import ghidra.framework.store.LockException; import ghidra.framework.store.LockException;
import ghidra.program.model.address.Address; import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressOverflowException; import ghidra.program.model.address.AddressOverflowException;
@ -28,7 +27,8 @@ import ghidra.util.exception.*;
/** /**
* Base command class for adding memory blocks. * Base command class for adding memory blocks.
*/ */
public abstract class AbstractAddMemoryBlockCmd implements Command { public abstract class AbstractAddMemoryBlockCmd implements Command<Program> {
protected String message; protected String message;
protected final String name; protected final String name;
protected final String comment; protected final String comment;
@ -82,8 +82,7 @@ public abstract class AbstractAddMemoryBlockCmd implements Command {
MemoryConflictException, AddressOverflowException, CancelledException; MemoryConflictException, AddressOverflowException, CancelledException;
@Override @Override
public boolean applyTo(DomainObject obj) { public boolean applyTo(Program program) {
Program program = (Program) obj;
try { try {
Memory memory = program.getMemory(); Memory memory = program.getMemory();
MemoryBlock block = createMemoryBlock(memory); MemoryBlock block = createMemoryBlock(memory);

View file

@ -16,7 +16,6 @@
package ghidra.app.cmd.memory; package ghidra.app.cmd.memory;
import ghidra.framework.cmd.BackgroundCommand; import ghidra.framework.cmd.BackgroundCommand;
import ghidra.framework.model.DomainObject;
import ghidra.framework.store.LockException; import ghidra.framework.store.LockException;
import ghidra.program.model.address.Address; import ghidra.program.model.address.Address;
import ghidra.program.model.listing.Program; 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 * Command that runs in the background to delete a memory block, as
* the delete may be a time consuming operation. * the delete may be a time consuming operation.
*/ */
public class DeleteBlockCmd extends BackgroundCommand { public class DeleteBlockCmd extends BackgroundCommand<Program> {
private Address[] blockAddresses; private Address[] blockAddresses;
private DeleteBlockListener listener; private DeleteBlockListener listener;
private boolean status; private boolean status;
@ -51,8 +50,8 @@ public class DeleteBlockCmd extends BackgroundCommand {
} }
@Override @Override
public boolean applyTo(DomainObject obj, TaskMonitor monitor) { public boolean applyTo(Program program, TaskMonitor monitor) {
Program program = (Program) obj;
Memory mem = program.getMemory(); Memory mem = program.getMemory();
if (!program.hasExclusiveAccess()) { if (!program.hasExclusiveAccess()) {

View file

@ -19,7 +19,6 @@ import java.util.*;
import java.util.function.Consumer; import java.util.function.Consumer;
import ghidra.framework.cmd.BackgroundCommand; import ghidra.framework.cmd.BackgroundCommand;
import ghidra.framework.model.DomainObject;
import ghidra.graph.GDirectedGraph; import ghidra.graph.GDirectedGraph;
import ghidra.graph.GraphFactory; import ghidra.graph.GraphFactory;
import ghidra.program.model.address.*; import ghidra.program.model.address.*;
@ -33,7 +32,7 @@ import ghidra.util.Msg;
import ghidra.util.exception.*; import ghidra.util.exception.*;
import ghidra.util.task.TaskMonitor; import ghidra.util.task.TaskMonitor;
public abstract class AbstractModularizationCmd extends BackgroundCommand { public abstract class AbstractModularizationCmd extends BackgroundCommand<Program> {
protected Program program; protected Program program;
private GroupPath groupPath; private GroupPath groupPath;
private String treeName; private String treeName;
@ -60,9 +59,9 @@ public abstract class AbstractModularizationCmd extends BackgroundCommand {
protected abstract void applyModel() throws CancelledException; protected abstract void applyModel() throws CancelledException;
@Override @Override
public boolean applyTo(DomainObject obj, TaskMonitor taskMonitor) { public boolean applyTo(Program p, TaskMonitor taskMonitor) {
program = (Program) obj; program = p;
monitor = taskMonitor; monitor = taskMonitor;
monitor.setIndeterminate(true); monitor.setIndeterminate(true);
ProgramModule rootModule = program.getListing().getRootModule(treeName); ProgramModule rootModule = program.getListing().getRootModule(treeName);

View file

@ -16,7 +16,6 @@
package ghidra.app.cmd.module; package ghidra.app.cmd.module;
import ghidra.framework.cmd.Command; import ghidra.framework.cmd.Command;
import ghidra.framework.model.DomainObject;
import ghidra.program.model.listing.*; import ghidra.program.model.listing.*;
import ghidra.program.model.mem.MemoryBlock; import ghidra.program.model.mem.MemoryBlock;
import ghidra.util.exception.DuplicateNameException; import ghidra.util.exception.DuplicateNameException;
@ -28,7 +27,7 @@ import ghidra.util.exception.DuplicateNameException;
* *
* *
*/ */
public class CreateDefaultTreeCmd implements Command { public class CreateDefaultTreeCmd implements Command<Program> {
private String treeName; private String treeName;
private String statusMsg; private String statusMsg;
@ -41,18 +40,15 @@ public class CreateDefaultTreeCmd implements Command {
this.treeName = treeName; this.treeName = treeName;
} }
/** @Override
* public boolean applyTo(Program program) {
* @see ghidra.framework.cmd.Command#applyTo(ghidra.framework.model.DomainObject)
*/
public boolean applyTo(DomainObject obj) {
Program program = (Program)obj;
Listing listing = program.getListing(); Listing listing = program.getListing();
try { try {
listing.createRootModule(treeName); listing.createRootModule(treeName);
renameFragments(program, treeName); renameFragments(program, treeName);
return true; return true;
} catch (DuplicateNameException e) { }
catch (DuplicateNameException e) {
statusMsg = e.getMessage(); statusMsg = e.getMessage();
} }
return false; return false;
@ -80,26 +76,23 @@ public class CreateDefaultTreeCmd implements Command {
private static void renameFragments(Program program, String treeName) { private static void renameFragments(Program program, String treeName) {
Listing listing = program.getListing(); Listing listing = program.getListing();
MemoryBlock[] blocks = program.getMemory().getBlocks(); MemoryBlock[] blocks = program.getMemory().getBlocks();
for (int i=0; i<blocks.length; i++) { for (MemoryBlock block : blocks) {
ProgramFragment fragment = listing.getFragment(treeName, ProgramFragment fragment = listing.getFragment(treeName, block.getStart());
blocks[i].getStart());
try { try {
fragment.setName(blocks[i].getName()); fragment.setName(block.getName());
} catch (DuplicateNameException e) { }
catch (DuplicateNameException e) {
// ignore
} }
} }
} }
/** @Override
* @see ghidra.framework.cmd.Command#getStatusMsg()
*/
public String getStatusMsg() { public String getStatusMsg() {
return statusMsg; return statusMsg;
} }
/** @Override
* @see ghidra.framework.cmd.Command#getName()
*/
public String getName() { public String getName() {
return "Create Tree " + treeName; return "Create Tree " + treeName;
} }

View file

@ -16,14 +16,13 @@
package ghidra.app.cmd.module; package ghidra.app.cmd.module;
import ghidra.framework.cmd.Command; import ghidra.framework.cmd.Command;
import ghidra.framework.model.DomainObject;
import ghidra.program.model.listing.*; import ghidra.program.model.listing.*;
import ghidra.util.exception.DuplicateNameException; import ghidra.util.exception.DuplicateNameException;
/** /**
* Command to create a folder in a program tree. * Command to create a folder in a program tree.
*/ */
public class CreateFolderCommand implements Command { public class CreateFolderCommand implements Command<Program> {
private String name; private String name;
private String statusMsg; private String statusMsg;
@ -41,11 +40,8 @@ public class CreateFolderCommand implements Command {
this.parentName = parentName; this.parentName = parentName;
} }
/** @Override
* @see ghidra.framework.cmd.Command#applyTo(ghidra.framework.model.DomainObject) public boolean applyTo(Program program) {
*/
public boolean applyTo(DomainObject obj) {
Program program = (Program)obj;
Listing listing = program.getListing(); Listing listing = program.getListing();
ProgramModule m = listing.getModule(treeName, parentName); ProgramModule m = listing.getModule(treeName, parentName);
if (m == null) { if (m == null) {
@ -56,7 +52,8 @@ public class CreateFolderCommand implements Command {
try { try {
m.createModule(name); m.createModule(name);
return true; return true;
} catch (DuplicateNameException e) { }
catch (DuplicateNameException e) {
statusMsg = name + " already exists"; statusMsg = name + " already exists";
} }
return false; return false;
@ -65,6 +62,7 @@ public class CreateFolderCommand implements Command {
/** /**
* @see ghidra.framework.cmd.Command#getStatusMsg() * @see ghidra.framework.cmd.Command#getStatusMsg()
*/ */
@Override
public String getStatusMsg() { public String getStatusMsg() {
return statusMsg; return statusMsg;
} }
@ -72,6 +70,7 @@ public class CreateFolderCommand implements Command {
/** /**
* @see ghidra.framework.cmd.Command#getName() * @see ghidra.framework.cmd.Command#getName()
*/ */
@Override
public String getName() { public String getName() {
return "Create Folder"; return "Create Folder";
} }

View file

@ -16,7 +16,6 @@
package ghidra.app.cmd.module; package ghidra.app.cmd.module;
import ghidra.framework.cmd.Command; import ghidra.framework.cmd.Command;
import ghidra.framework.model.DomainObject;
import ghidra.program.model.listing.*; import ghidra.program.model.listing.*;
import ghidra.util.exception.DuplicateNameException; import ghidra.util.exception.DuplicateNameException;
@ -25,7 +24,7 @@ import ghidra.util.exception.DuplicateNameException;
* *
* *
*/ */
public class CreateFragmentCmd implements Command { public class CreateFragmentCmd implements Command<Program> {
private String name; private String name;
private String statusMsg; private String statusMsg;
@ -50,8 +49,8 @@ public class CreateFragmentCmd implements Command {
* @return false if the fragment was not created * @return false if the fragment was not created
* @see ghidra.framework.cmd.Command#applyTo(ghidra.framework.model.DomainObject) * @see ghidra.framework.cmd.Command#applyTo(ghidra.framework.model.DomainObject)
*/ */
public boolean applyTo(DomainObject obj) { @Override
Program program = (Program)obj; public boolean applyTo(Program program) {
Listing listing = program.getListing(); Listing listing = program.getListing();
ProgramModule m = listing.getModule(treeName, parentName); ProgramModule m = listing.getModule(treeName, parentName);
if (m == null) { if (m == null) {
@ -62,22 +61,19 @@ public class CreateFragmentCmd implements Command {
try { try {
m.createFragment(name); m.createFragment(name);
return true; return true;
} catch (DuplicateNameException e) { }
catch (DuplicateNameException e) {
statusMsg = name + " already exists"; statusMsg = name + " already exists";
} }
return false; return false;
} }
/** @Override
* @see ghidra.framework.cmd.Command#getStatusMsg()
*/
public String getStatusMsg() { public String getStatusMsg() {
return statusMsg; return statusMsg;
} }
/** @Override
* @see ghidra.framework.cmd.Command#getName()
*/
public String getName() { public String getName() {
return "Create Fragment"; return "Create Fragment";
} }

View file

@ -1,6 +1,5 @@
/* ### /* ###
* IP: GHIDRA * IP: GHIDRA
* REVIEWED: YES
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -17,7 +16,6 @@
package ghidra.app.cmd.module; package ghidra.app.cmd.module;
import ghidra.framework.cmd.Command; import ghidra.framework.cmd.Command;
import ghidra.framework.model.DomainObject;
import ghidra.program.model.listing.Program; import ghidra.program.model.listing.Program;
/** /**
@ -25,7 +23,7 @@ import ghidra.program.model.listing.Program;
* *
* *
*/ */
public class DeleteTreeCmd implements Command { public class DeleteTreeCmd implements Command<Program> {
private String treeName; private String treeName;
/** /**
@ -36,25 +34,17 @@ public class DeleteTreeCmd implements Command {
this.treeName = treeName; this.treeName = treeName;
} }
/** @Override
* public boolean applyTo(Program program) {
* @see ghidra.framework.cmd.Command#applyTo(ghidra.framework.model.DomainObject)
*/
public boolean applyTo(DomainObject obj) {
Program program = (Program)obj;
return program.getListing().removeTree(treeName); return program.getListing().removeTree(treeName);
} }
/** @Override
* @see ghidra.framework.cmd.Command#getStatusMsg()
*/
public String getStatusMsg() { public String getStatusMsg() {
return null; return null;
} }
/** @Override
* @see ghidra.framework.cmd.Command#getName()
*/
public String getName() { public String getName() {
return "Delete " + treeName; return "Delete " + treeName;
} }

View file

@ -16,7 +16,6 @@
package ghidra.app.cmd.module; package ghidra.app.cmd.module;
import ghidra.framework.cmd.Command; import ghidra.framework.cmd.Command;
import ghidra.framework.model.DomainObject;
import ghidra.program.model.listing.*; import ghidra.program.model.listing.*;
import ghidra.util.Msg; import ghidra.util.Msg;
import ghidra.util.exception.NotEmptyException; import ghidra.util.exception.NotEmptyException;
@ -28,7 +27,7 @@ import ghidra.util.exception.NotFoundException;
* *
* *
*/ */
public class MergeFolderCmd implements Command { public class MergeFolderCmd implements Command<Program> {
private String treeName; private String treeName;
private String folderName; private String folderName;
@ -49,13 +48,9 @@ public class MergeFolderCmd implements Command {
this.parentName = parentName; this.parentName = parentName;
} }
/* (non-Javadoc)
* @see ghidra.framework.cmd.Command#applyTo(ghidra.framework.model.DomainObject)
*/
@Override @Override
public boolean applyTo(DomainObject obj) { public boolean applyTo(Program program) {
Program program = (Program) obj;
Listing listing = program.getListing(); Listing listing = program.getListing();
ProgramModule parentModule = listing.getModule(treeName, parentName); ProgramModule parentModule = listing.getModule(treeName, parentName);
@ -66,12 +61,12 @@ public class MergeFolderCmd implements Command {
} }
Group[] groups = module.getChildren(); 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 // first check to make sure that the parent module
// does not alreay contain tree group // does not alreay contain tree group
String name = groups[i].getName(); String name = group.getName();
ProgramModule m = listing.getModule(treeName, name); ProgramModule m = listing.getModule(treeName, name);
ProgramFragment f = null; ProgramFragment f = null;
try { try {
@ -100,8 +95,8 @@ public class MergeFolderCmd implements Command {
try { try {
ProgramModule m = listing.getModule(treeName, folderName); ProgramModule m = listing.getModule(treeName, folderName);
ProgramModule[] parents = m.getParents(); ProgramModule[] parents = m.getParents();
for (int i = 0; i < parents.length; i++) { for (ProgramModule parent : parents) {
parents[i].removeChild(folderName); parent.removeChild(folderName);
} }
return true; return true;
} }
@ -111,17 +106,11 @@ public class MergeFolderCmd implements Command {
return false; return false;
} }
/* (non-Javadoc)
* @see ghidra.framework.cmd.Command#getStatusMsg()
*/
@Override @Override
public String getStatusMsg() { public String getStatusMsg() {
return errMsg; return errMsg;
} }
/* (non-Javadoc)
* @see ghidra.framework.cmd.Command#getName()
*/
@Override @Override
public String getName() { public String getName() {
return "Merge " + folderName + " with Parent"; return "Merge " + folderName + " with Parent";

View file

@ -19,7 +19,6 @@ import java.util.*;
import ghidra.app.services.BlockModelService; import ghidra.app.services.BlockModelService;
import ghidra.framework.cmd.BackgroundCommand; import ghidra.framework.cmd.BackgroundCommand;
import ghidra.framework.model.DomainObject;
import ghidra.framework.plugintool.PluginTool; import ghidra.framework.plugintool.PluginTool;
import ghidra.program.model.address.AddressRange; import ghidra.program.model.address.AddressRange;
import ghidra.program.model.address.AddressRangeIterator; 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. * 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 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. * 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<Program> {
private static final String NEW_MODULE_SUFFIX = " [Subroutine Tree]"; private static final String NEW_MODULE_SUFFIX = " [Subroutine Tree]";
private static final String PROGRAM_CHANGED_MESSAGE = private static final String PROGRAM_CHANGED_MESSAGE =
@ -71,14 +67,9 @@ public class ModuleAlgorithmCmd extends BackgroundCommand {
this.partitioningModelName = partitioningModelName; this.partitioningModelName = partitioningModelName;
} }
/**
*
* @see ghidra.framework.cmd.BackgroundCommand#applyTo(ghidra.framework.model.DomainObject, ghidra.util.task.TaskMonitor)
*/
@Override @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); ProgramModule root = program.getListing().getRootModule(treeName);
try { try {
@ -103,13 +94,6 @@ public class ModuleAlgorithmCmd extends BackgroundCommand {
this.tool = tool; this.tool = tool;
} }
/**
*
* @param monitor
* @throws NotFoundException
* @throws NotEmptyException
* @throws DuplicateNameException
*/
private boolean applyModel(Program program, ProgramModule root, TaskMonitor monitor) private boolean applyModel(Program program, ProgramModule root, TaskMonitor monitor)
throws NotFoundException, NotEmptyException, DuplicateNameException { throws NotFoundException, NotEmptyException, DuplicateNameException {
@ -125,9 +109,8 @@ public class ModuleAlgorithmCmd extends BackgroundCommand {
(SubroutineBlockModel) blockModelService.getActiveSubroutineModel(program); (SubroutineBlockModel) blockModelService.getActiveSubroutineModel(program);
} }
else { else {
partitioningModel = partitioningModel = (SubroutineBlockModel) blockModelService
(SubroutineBlockModel) blockModelService.getNewModelByName(partitioningModelName, .getNewModelByName(partitioningModelName, program);
program);
} }
SubroutineBlockModel baseModel = partitioningModel.getBaseSubroutineModel(); SubroutineBlockModel baseModel = partitioningModel.getBaseSubroutineModel();
@ -315,6 +298,7 @@ public class ModuleAlgorithmCmd extends BackgroundCommand {
module.setName(baseName + numKidsPrefix + module.getNumChildren() + "]"); module.setName(baseName + numKidsPrefix + module.getNumChildren() + "]");
} }
catch (DuplicateNameException e) { catch (DuplicateNameException e) {
// ignore
} }
} }
} }

Some files were not shown because too many files have changed in this diff Show more