This action assembles a block of instructions starting at the cursor. One action is
+ presented per language configured at the current location. Other languages may also be
+ presented if the only thing that varies is the default disassembly context, e.g., configuring
+ ARM will also allow THUMB assembly.
+
+
Patch Instruction
This action assembles an instruction at the cursor. One action is presented per language
configured at the current location. Other languages may also be presented if the only thing
diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/disassemble/AbstractTraceAssemblePatchAction.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/disassemble/AbstractTraceAssemblePatchAction.java
new file mode 100644
index 0000000000..1c8b7b0ea0
--- /dev/null
+++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/disassemble/AbstractTraceAssemblePatchAction.java
@@ -0,0 +1,46 @@
+/* ###
+ * 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.plugin.core.debug.disassemble;
+
+import ghidra.app.context.ListingActionContext;
+import ghidra.app.plugin.core.assembler.AbstractAssemblePatchDialog;
+import ghidra.app.plugin.core.assembler.AssemblePatchAction;
+import ghidra.program.model.address.Address;
+import ghidra.program.model.lang.RegisterValue;
+import ghidra.program.model.listing.Instruction;
+import ghidra.trace.model.guest.TracePlatform;
+import ghidra.trace.model.program.TraceProgramView;
+
+public abstract class AbstractTraceAssemblePatchAction extends AssemblePatchAction {
+
+ public AbstractTraceAssemblePatchAction(DebuggerDisassemblerPlugin plugin, String name) {
+ super(plugin, name);
+ }
+
+ protected abstract TracePlatform getPlatform(TraceProgramView view, Address entry);
+
+ @Override
+ protected AbstractAssemblePatchDialog> newDialog(ListingActionContext ctx) {
+ if (!(ctx.getProgram() instanceof TraceProgramView view)) {
+ return null;
+ }
+ Address entry = ctx.getAddress();
+ Instruction ins = view.getListing().getInstructionContaining(entry);
+ RegisterValue initialContext = getInitialContext(ins, view, entry);
+ return new TraceAssemblePatchDialog(plugin.getTool(), ctx.getNavigatable(),
+ getPlatform(view, entry), view, entry, initialContext);
+ }
+}
diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/disassemble/AbstractTracePatchInstructionAction.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/disassemble/AbstractTracePatchInstructionAction.java
index e148abbb30..8d587051c0 100644
--- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/disassemble/AbstractTracePatchInstructionAction.java
+++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/disassemble/AbstractTracePatchInstructionAction.java
@@ -37,6 +37,31 @@ import ghidra.util.Msg;
import ghidra.util.task.TaskMonitor;
public abstract class AbstractTracePatchInstructionAction extends PatchInstructionAction {
+ protected class TraceAssemblyDualTextField extends AssemblyDualTextField {
+ protected class TraceAssemblyDualTextAutocompletionModel
+ extends AssemblyDualTextAutocompletionModel {
+ AssemblyPatternBlock ctx = null;
+
+ @Override
+ protected AssemblyPatternBlock getContext() {
+ return ctx;
+ }
+
+ @Override
+ public void setAddress(Address address) {
+ super.setAddress(address);
+ RegisterValue rv = getContextValue(getCodeUnit());
+ ctx = rv == null ? AssemblyPatternBlock.nop()
+ : AssemblyPatternBlock.fromRegisterValue(rv).fillMask();
+ }
+ }
+
+ @Override
+ protected AssemblyDualTextAutocompletionModel newAutocompletionModel() {
+ return new TraceAssemblyDualTextAutocompletionModel();
+ }
+ }
+
protected final DebuggerDisassemblerPlugin plugin;
public AbstractTracePatchInstructionAction(DebuggerDisassemblerPlugin plugin, String name) {
@@ -57,22 +82,7 @@ public abstract class AbstractTracePatchInstructionAction extends PatchInstructi
@Override
protected AssemblyDualTextField newAssemblyDualTextField() {
- return new AssemblyDualTextField() {
- AssemblyPatternBlock ctx = null;
-
- @Override
- protected AssemblyPatternBlock getContext() {
- return ctx;
- }
-
- @Override
- public void setAddress(Address address) {
- super.setAddress(address);
- RegisterValue rv = getContextValue(getCodeUnit());
- ctx = rv == null ? AssemblyPatternBlock.nop()
- : AssemblyPatternBlock.fromRegisterValue(rv).fillMask();
- }
- };
+ return new TraceAssemblyDualTextField();
}
@Override
@@ -150,7 +160,14 @@ public abstract class AbstractTracePatchInstructionAction extends PatchInstructi
}
AddressSetView set = new AddressSet(address, address.add(data.length - 1));
- TraceDisassembleCommand dis = new TraceDisassembleCommand(platform, address, set);
+ TraceDisassembleCommand dis = new TraceDisassembleCommand(platform, address, set) {
+ @Override
+ public boolean applyTo(TraceProgramView view, TaskMonitor monitor) {
+ boolean result = super.applyTo(view, monitor);
+ doGoToNext(data.length);
+ return result;
+ }
+ };
if (contextValue != null) {
dis.setInitialContext(contextValue);
}
diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/disassemble/CurrentPlatformTraceAssemblePatchAction.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/disassemble/CurrentPlatformTraceAssemblePatchAction.java
new file mode 100644
index 0000000000..6867e89f95
--- /dev/null
+++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/disassemble/CurrentPlatformTraceAssemblePatchAction.java
@@ -0,0 +1,46 @@
+/* ###
+ * 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.plugin.core.debug.disassemble;
+
+import docking.ActionContext;
+import ghidra.app.context.ListingActionContext;
+import ghidra.program.model.address.Address;
+import ghidra.program.model.listing.Instruction;
+import ghidra.trace.model.guest.TracePlatform;
+import ghidra.trace.model.listing.TraceInstruction;
+import ghidra.trace.model.program.TraceProgramView;
+
+public class CurrentPlatformTraceAssemblePatchAction extends AbstractTraceAssemblePatchAction {
+
+ public CurrentPlatformTraceAssemblePatchAction(DebuggerDisassemblerPlugin plugin) {
+ super(plugin, "Assemble");
+ }
+
+ @Override
+ protected boolean isApplicableToContext(ActionContext context) {
+ return super.isApplicableToContext(context) &&
+ context instanceof ListingActionContext lac && lac.getNavigatable().isDynamic();
+ }
+
+ @Override
+ protected TracePlatform getPlatform(TraceProgramView view, Address entry) {
+ Instruction ins = view.getListing().getInstructionContaining(entry);
+ if (!(ins instanceof TraceInstruction tins)) { // includes null
+ return view.getTrace().getPlatformManager().getHostPlatform();
+ }
+ return tins.getPlatform();
+ }
+}
diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/disassemble/DebuggerDisassemblerPlugin.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/disassemble/DebuggerDisassemblerPlugin.java
index e3f04a5a2a..061b1b4532 100644
--- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/disassemble/DebuggerDisassemblerPlugin.java
+++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/disassemble/DebuggerDisassemblerPlugin.java
@@ -171,6 +171,7 @@ public class DebuggerDisassemblerPlugin extends Plugin implements PopupActionPro
CurrentPlatformTraceDisassembleAction actionDisassemble;
CurrentPlatformTracePatchInstructionAction actionPatchInstruction;
TracePatchDataAction actionPatchData;
+ CurrentPlatformTraceAssemblePatchAction actionAssemblePatch;
public DebuggerDisassemblerPlugin(PluginTool tool) {
super(tool);
@@ -187,10 +188,12 @@ public class DebuggerDisassemblerPlugin extends Plugin implements PopupActionPro
actionDisassemble = new CurrentPlatformTraceDisassembleAction(this);
actionPatchInstruction = new CurrentPlatformTracePatchInstructionAction(this);
actionPatchData = new TracePatchDataAction(this);
+ actionAssemblePatch = new CurrentPlatformTraceAssemblePatchAction(this);
tool.addAction(actionDisassemble);
tool.addAction(actionPatchInstruction);
tool.addAction(actionPatchData);
+ tool.addAction(actionAssemblePatch);
}
/**
@@ -222,6 +225,7 @@ public class DebuggerDisassemblerPlugin extends Plugin implements PopupActionPro
for (LanguageID langID : getAlternativeLanguageIDs(platform.getLanguage())) {
result.add(new FixedPlatformTraceDisassembleAction(this, langID, platform));
result.add(new FixedPlatformTracePatchInstructionAction(this, langID, platform));
+ result.add(new FixedPlatformTraceAssemblePatchAction(this, langID, platform));
}
}
diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/disassemble/FixedPlatformTraceAssemblePatchAction.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/disassemble/FixedPlatformTraceAssemblePatchAction.java
new file mode 100644
index 0000000000..4c1109dcf7
--- /dev/null
+++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/disassemble/FixedPlatformTraceAssemblePatchAction.java
@@ -0,0 +1,61 @@
+/* ###
+ * 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.plugin.core.debug.disassemble;
+
+import docking.action.MenuData;
+import ghidra.app.plugin.core.assembler.AbstractPatchAction;
+import ghidra.program.model.address.Address;
+import ghidra.program.model.lang.*;
+import ghidra.program.model.listing.Instruction;
+import ghidra.program.model.listing.Program;
+import ghidra.trace.model.guest.TracePlatform;
+import ghidra.trace.model.listing.TraceInstruction;
+import ghidra.trace.model.program.TraceProgramView;
+
+public class FixedPlatformTraceAssemblePatchAction extends AbstractTraceAssemblePatchAction {
+
+ private final LanguageID altLangID;
+ private final TracePlatform platform;
+
+ public FixedPlatformTraceAssemblePatchAction(DebuggerDisassemblerPlugin plugin,
+ LanguageID altLangID, TracePlatform platform) {
+ this.altLangID = altLangID;
+ this.platform = platform;
+ super(plugin, "Assemble using " + altLangID);
+ }
+
+ @Override
+ protected MenuData createMenuData(String name) {
+ MenuData menuData =
+ new MenuData(new String[] { "Assemble using...", altLangID.toString() });
+ menuData.setParentMenuGroup(AbstractPatchAction.MENU_GROUP);
+ return menuData;
+ }
+
+ @Override
+ protected TracePlatform getPlatform(TraceProgramView view, Address entry) {
+ return platform;
+ }
+
+ @Override
+ protected RegisterValue getInitialContext(Instruction ins, Program program, Address entry) {
+ Language language = ins instanceof TraceInstruction tins
+ ? tins.getLanguage()
+ : program.getLanguage();
+ return DebuggerDisassemblerPlugin.deriveAlternativeDefaultContext(language, altLangID,
+ entry);
+ }
+}
diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/disassemble/FixedPlatformTraceDisassembleAction.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/disassemble/FixedPlatformTraceDisassembleAction.java
index bb5e2a531b..83a5e481f3 100644
--- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/disassemble/FixedPlatformTraceDisassembleAction.java
+++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/disassemble/FixedPlatformTraceDisassembleAction.java
@@ -4,9 +4,9 @@
* 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.
@@ -16,6 +16,7 @@
package ghidra.app.plugin.core.debug.disassemble;
import docking.action.MenuData;
+import ghidra.app.plugin.core.assembler.AbstractPatchAction;
import ghidra.program.model.lang.LanguageID;
import ghidra.trace.model.guest.TracePlatform;
import ghidra.trace.model.program.TraceProgramView;
@@ -26,13 +27,13 @@ public class FixedPlatformTraceDisassembleAction extends AbstractTraceDisassembl
public FixedPlatformTraceDisassembleAction(DebuggerDisassemblerPlugin plugin,
LanguageID altLangID, TracePlatform platform) {
- super(plugin, "Disassemble Trace as " + altLangID);
this.altLangID = altLangID;
this.platform = platform;
+ super(plugin, "Disassemble Trace as " + altLangID);
- // TODO: Human-readable description?
- setPopupMenuData(
- new MenuData(new String[] { "Disassemble as " + altLangID }, "Disassembly"));
+ MenuData menuData = new MenuData(new String[] { "Disassemble as", altLangID.toString() });
+ menuData.setParentMenuGroup(AbstractPatchAction.MENU_GROUP);
+ setPopupMenuData(menuData);
}
@Override
diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/disassemble/FixedPlatformTracePatchInstructionAction.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/disassemble/FixedPlatformTracePatchInstructionAction.java
index 135de2fd7f..687d95e352 100644
--- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/disassemble/FixedPlatformTracePatchInstructionAction.java
+++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/disassemble/FixedPlatformTracePatchInstructionAction.java
@@ -4,9 +4,9 @@
* 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.
@@ -15,6 +15,8 @@
*/
package ghidra.app.plugin.core.debug.disassemble;
+import docking.action.MenuData;
+import ghidra.app.plugin.core.assembler.AbstractPatchAction;
import ghidra.program.model.lang.LanguageID;
import ghidra.program.model.listing.CodeUnit;
import ghidra.trace.model.guest.TracePlatform;
@@ -25,11 +27,18 @@ public class FixedPlatformTracePatchInstructionAction extends AbstractTracePatch
public FixedPlatformTracePatchInstructionAction(DebuggerDisassemblerPlugin plugin,
LanguageID altLangID, TracePlatform platform) {
- super(plugin, "Patch Instruction using " + altLangID);
- setKeyBindingData(null);
-
this.altLangID = altLangID;
this.platform = platform;
+ super(plugin, "Patch Instruction using " + altLangID);
+ setKeyBindingData(null);
+ }
+
+ @Override
+ protected MenuData createMenuData(String name) {
+ MenuData menuData =
+ new MenuData(new String[] { "Patch Instruction using", altLangID.toString() });
+ menuData.setParentMenuGroup(AbstractPatchAction.MENU_GROUP);
+ return menuData;
}
@Override
diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/disassemble/TraceAssemblePatchDialog.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/disassemble/TraceAssemblePatchDialog.java
new file mode 100644
index 0000000000..ecbd1b5d03
--- /dev/null
+++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/disassemble/TraceAssemblePatchDialog.java
@@ -0,0 +1,56 @@
+/* ###
+ * 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.plugin.core.debug.disassemble;
+
+import java.util.List;
+
+import ghidra.app.nav.Navigatable;
+import ghidra.app.plugin.assembler.Assembler;
+import ghidra.app.plugin.assembler.Assemblers;
+import ghidra.app.plugin.core.assembler.AbstractAssemblePatchDialog;
+import ghidra.app.plugin.core.assembler.AbstractPatchAssemblyCommand;
+import ghidra.framework.plugintool.PluginTool;
+import ghidra.program.model.address.Address;
+import ghidra.program.model.lang.Language;
+import ghidra.program.model.lang.RegisterValue;
+import ghidra.trace.model.guest.TracePlatform;
+import ghidra.trace.model.program.TraceProgramView;
+
+public class TraceAssemblePatchDialog extends AbstractAssemblePatchDialog {
+ private final TracePlatform platform;
+
+ protected TraceAssemblePatchDialog(PluginTool tool, Navigatable navigatable,
+ TracePlatform platform, TraceProgramView program, Address entry,
+ RegisterValue initialContext) {
+ this.platform = platform;
+ super(tool, navigatable, program, entry, initialContext);
+ }
+
+ @Override
+ protected AbstractPatchAssemblyCommand newPatchCommand(List lines) {
+ return new TracePatchAssemblyCommand(platform, assembler, lines, entry, initialContext);
+ }
+
+ @Override
+ protected Language getLanguage() {
+ return platform.getLanguage();
+ }
+
+ @Override
+ protected Assembler getAssembler() {
+ return Assemblers.getAssembler(getLanguage());
+ }
+}
diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/disassemble/TracePatchAssemblyCommand.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/disassemble/TracePatchAssemblyCommand.java
new file mode 100644
index 0000000000..33c5ee3e2a
--- /dev/null
+++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/disassemble/TracePatchAssemblyCommand.java
@@ -0,0 +1,52 @@
+/* ###
+ * 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.plugin.core.debug.disassemble;
+
+import java.util.List;
+
+import ghidra.app.plugin.assembler.Assembler;
+import ghidra.app.plugin.core.assembler.AbstractPatchAssemblyCommand;
+import ghidra.framework.cmd.Command;
+import ghidra.program.model.address.Address;
+import ghidra.program.model.address.AddressSetView;
+import ghidra.program.model.lang.RegisterValue;
+import ghidra.trace.model.guest.TracePlatform;
+import ghidra.trace.model.program.TraceProgramView;
+
+public class TracePatchAssemblyCommand extends AbstractPatchAssemblyCommand {
+
+ private final TracePlatform platform;
+
+ public TracePatchAssemblyCommand(TracePlatform platform, Assembler asm, List lines,
+ Address entry, RegisterValue initialContext) {
+ this.platform = platform;
+ super(asm, lines, entry, initialContext);
+ }
+
+ public TracePatchAssemblyCommand(TracePlatform platform, Assembler asm, String string,
+ Address entry, RegisterValue initialContext) {
+ this.platform = platform;
+ super(asm, string, entry, initialContext);
+ }
+
+ @Override
+ protected Command newDisassembleCommand(AddressSetView set,
+ TraceProgramView program) {
+ TraceDisassembleCommand dis = new TraceDisassembleCommand(platform, entry, set);
+ dis.setInitialContext(initialContext);
+ return dis;
+ }
+}
diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/disassemble/TracePatchDataAction.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/disassemble/TracePatchDataAction.java
index 682929b88f..cceeb22298 100644
--- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/disassemble/TracePatchDataAction.java
+++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/disassemble/TracePatchDataAction.java
@@ -62,6 +62,7 @@ public class TracePatchDataAction extends PatchDataAction {
try {
editor.setVariable(address, encoded).get(1, TimeUnit.SECONDS);
+ doGoToNext(encoded.length);
// Let the trace do everything regarding existing units
return true;
}
diff --git a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/stack/StackUnwinderTest.java b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/stack/StackUnwinderTest.java
index 4a860f895d..43db79ecda 100644
--- a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/stack/StackUnwinderTest.java
+++ b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/stack/StackUnwinderTest.java
@@ -654,8 +654,7 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest {
Language language = asm.getLanguage();
Register regCtx = language.getContextBaseRegister();
Register regT = language.getRegister("T");
- RegisterValue rvDefault = new RegisterValue(regCtx,
- asm.getContextAt(entry).toBigInteger(regCtx.getNumBytes()));
+ RegisterValue rvDefault = asm.getContextAt(entry).toRegisterValue(regCtx);
RegisterValue rvThumb = rvDefault.assign(regT, BigInteger.ONE);
AssemblyPatternBlock ctxThumb = AssemblyPatternBlock.fromRegisterValue(rvThumb);
diff --git a/Ghidra/Extensions/SymbolicSummaryZ3/src/main/java/ghidra/pcode/emu/symz3/SymZ3EmulatorFactory.java b/Ghidra/Extensions/SymbolicSummaryZ3/src/main/java/ghidra/pcode/emu/symz3/SymZ3EmulatorFactory.java
index e410508a41..0acb5cf0de 100644
--- a/Ghidra/Extensions/SymbolicSummaryZ3/src/main/java/ghidra/pcode/emu/symz3/SymZ3EmulatorFactory.java
+++ b/Ghidra/Extensions/SymbolicSummaryZ3/src/main/java/ghidra/pcode/emu/symz3/SymZ3EmulatorFactory.java
@@ -25,13 +25,13 @@ import ghidra.pcode.exec.trace.TraceEmulationIntegration.Writer;
import ghidra.pcode.exec.trace.data.PcodeTraceAccess;
/**
- * An emulator factory for making the {@link SymZ3DebuggerPcodeEmulator} discoverable to the UI
- *
+ * An emulator factory for making the {@link SymZ3PcodeEmulator} discoverable to the UI
*
* This is the final class to create a full Debugger-integrated emulator. This class is what makes
* it appear in the menu of possible emulators the user may configure.
*/
public class SymZ3EmulatorFactory implements EmulatorFactory {
+ public static final String TITLE = "Symbolic Z3 Summary with Concrete Emulation";
public static Writer delayedWriteTrace(PcodeTraceAccess access) {
Writer writer = TraceEmulationIntegration.bytesDelayedWrite(access);
@@ -45,7 +45,7 @@ public class SymZ3EmulatorFactory implements EmulatorFactory {
@Override
public String getTitle() {
- return "Symbolic Z3 Summary with Concrete Emulation";
+ return TITLE;
}
@Override
diff --git a/Ghidra/Extensions/SymbolicSummaryZ3/src/main/java/ghidra/symz3/gui/Z3SummaryProvider.java b/Ghidra/Extensions/SymbolicSummaryZ3/src/main/java/ghidra/symz3/gui/Z3SummaryProvider.java
index e946ab76a0..eeb937effe 100644
--- a/Ghidra/Extensions/SymbolicSummaryZ3/src/main/java/ghidra/symz3/gui/Z3SummaryProvider.java
+++ b/Ghidra/Extensions/SymbolicSummaryZ3/src/main/java/ghidra/symz3/gui/Z3SummaryProvider.java
@@ -15,8 +15,10 @@
*/
package ghidra.symz3.gui;
-import java.awt.BorderLayout;
+import java.awt.*;
+import java.util.List;
import java.util.Objects;
+import java.util.stream.Stream;
import javax.swing.*;
@@ -88,8 +90,9 @@ public class Z3SummaryProvider extends ComponentProviderAdapter {
String style = "";
JPanel mainPanel = new JPanel(new BorderLayout());
- JSplitPane submainPanel = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
+ JSplitPane summaryPanel = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
JSplitPane codePanel = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
+ JPanel fixPanel = new JPanel(new GridBagLayout());
Z3SummaryInformationPanel information;
Z3SummaryPcodeLogPanel ops;
@@ -120,15 +123,30 @@ public class Z3SummaryProvider extends ComponentProviderAdapter {
ops = new Z3SummaryPcodeLogPanel(this);
instructions = new Z3SummaryInstructionLogPanel(this);
- JPanel summaryPanel = new JPanel(new BorderLayout());
- summaryPanel.add(new JScrollPane(information));
codePanel.setTopComponent(instructions);
codePanel.setBottomComponent(ops);
codePanel.setDividerLocation(0.4);
- submainPanel.setRightComponent(summaryPanel);
- submainPanel.setLeftComponent(codePanel);
- mainPanel.add(submainPanel);
- setFactoryToZ3();
+ summaryPanel.setRightComponent(instructions);
+ summaryPanel.setLeftComponent(codePanel);
+ mainPanel.add(summaryPanel);
+
+ GridBagConstraints gbc = new GridBagConstraints();
+ gbc.gridwidth = GridBagConstraints.REMAINDER;
+ gbc.anchor = GridBagConstraints.NORTH;
+ fixPanel.add(new JLabel("""
+
+
Z3 Emulator is not active
+
Press the button below to configure this tool for %s
""".formatted(
+ SymZ3EmulatorFactory.TITLE)));
+ JPanel buttons = new JPanel(new GridBagLayout());
+ gbc.anchor = GridBagConstraints.CENTER;
+ gbc.fill = GridBagConstraints.HORIZONTAL;
+
+ JButton buttonFix = new JButton("Fix");
+ buttonFix.addActionListener(evt -> setFactoryToZ3());
+ buttons.add(buttonFix);
+ gbc.weighty = 1;
+ fixPanel.add(buttons, gbc);
}
public void updateSummary() {
@@ -148,8 +166,30 @@ public class Z3SummaryProvider extends ComponentProviderAdapter {
PcodeMachine> emu = emulationService.getCachedEmulator(trace, time);
if (emu instanceof SymZ3PcodeEmulator z3Emu) {
populateSummaryFromEmulator(z3Emu);
+ ensureMainPanel(summaryPanel);
}
+ else {
+ clearSummary();
+ ensureMainPanel(fixPanel);
+ }
+ }
+ private static boolean contains(Container container, Component component) {
+ int count = container.getComponentCount();
+ for (int i = 0; i < count; i++) {
+ if (container.getComponent(i) == component) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private void ensureMainPanel(Component component) {
+ if (contains(mainPanel, component)) {
+ return;
+ }
+ mainPanel.removeAll();
+ mainPanel.add(component);
}
private void setFactoryToZ3() {
@@ -162,6 +202,12 @@ public class Z3SummaryProvider extends ComponentProviderAdapter {
}
}
+ public void clearSummary() {
+ information.setInformation(Stream.of(), Stream.of());
+ ops.setLog(List.of());
+ instructions.setLog(List.of());
+ }
+
public void populateSummaryFromEmulator(SymZ3PcodeEmulator emu) {
try (Context ctx = new Context()) {
Z3InfixPrinter z3p = new Z3InfixPrinter(ctx);
diff --git a/Ghidra/Features/Base/ghidra_scripts/RepairDisassemblyScript.java b/Ghidra/Features/Base/ghidra_scripts/RepairDisassemblyScript.java
index 60dc43af41..66f03121fa 100644
--- a/Ghidra/Features/Base/ghidra_scripts/RepairDisassemblyScript.java
+++ b/Ghidra/Features/Base/ghidra_scripts/RepairDisassemblyScript.java
@@ -4,9 +4,9 @@
* 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.
@@ -20,6 +20,6 @@ public class RepairDisassemblyScript extends GhidraScript {
@Override
protected void run() throws Exception {
ReDisassembler dis = new ReDisassembler(currentProgram);
- dis.disasemble(currentAddress, monitor);
+ dis.disassemble(currentAddress, monitor);
}
}
diff --git a/Ghidra/Features/Base/src/main/help/help/topics/AssemblerPlugin/Assembler.htm b/Ghidra/Features/Base/src/main/help/help/topics/AssemblerPlugin/Assembler.htm
index 782ecf4628..64a94b8cbc 100644
--- a/Ghidra/Features/Base/src/main/help/help/topics/AssemblerPlugin/Assembler.htm
+++ b/Ghidra/Features/Base/src/main/help/help/topics/AssemblerPlugin/Assembler.htm
@@ -19,7 +19,8 @@ ol.ratings li {
Assembler
-
+
Assembly Editor
@@ -28,7 +29,7 @@ ol.ratings li {
Actions
-
There are two actions: One for instructions and one for data.
+
There are three actions: One for blocks, one for single instructions, and one for data.
This action is similar to Patch Instruction except that you can enter several instructions
+ in a sequence. See Copy
+ Assembly Code as a means of copying assembly passages from other parts of the program. The
+ dialog is fairly straightfoward: You enter lines of assembly code in the top text area, and the
+ table will display the tentative assembly result. The default columns are the Address and the
+ Assembly, which display the starting address and assembly of each instruction. There are
+ additional columns for diagnostics, including Bytes, Context, and Error. These display the
+ resulting machine code bytes, the input (dis)assembly context, and if applicable, any errors
+ encountered during assembly. When an error is encountered, the offending instruction's Assembly
+ cell is rendered in red, and no further instructions are assembled.
+
Patch Data
This action is available at initialized memory addresses having a data unit with a type that
diff --git a/Ghidra/Features/Base/src/main/help/help/topics/ClipboardPlugin/Clipboard.htm b/Ghidra/Features/Base/src/main/help/help/topics/ClipboardPlugin/Clipboard.htm
index d23b41ecf7..caa37e8aac 100644
--- a/Ghidra/Features/Base/src/main/help/help/topics/ClipboardPlugin/Clipboard.htm
+++ b/Ghidra/Features/Base/src/main/help/help/topics/ClipboardPlugin/Clipboard.htm
@@ -29,7 +29,7 @@
Copies the currently selected items. The behavior will be dependent on the specific window
you copy from. Generally, copy means to place a copy of whatever is selected onto the
@@ -98,7 +96,7 @@
-
Paste
+
Paste
Pastes the clipboard contents to the current location. The behavior will be dependent on
the specific window you paste to. Generally, paste means to insert a copy of whatever is on
@@ -115,7 +113,8 @@
Copy Special
-
+
The copy special dialog allows you to copy the selected information in a specific format.
@@ -128,13 +127,14 @@
with the standard copy and paste operations (it is only visible when the last selected format
is applicable). This feature allows you to repeatedly copy the same format quickly from
either the menu or by binding a key to it. To specify a key binding, select EditTool Options, click on Key Bindings,
- and choose the action for which you want to define a key. The action for repeat copying of
- the last format is called Copy Special Again. When available, the popup menu
- appears as follows:
+ alt="arrow" border="0" src="help/shared/arrow.gif">Tool Options, click on Key
+ Bindings, and choose the action for which you want to define a key. The action for
+ repeat copying of the last format is called Copy Special Again. When available,
+ the popup menu appears as follows:
-
+
@@ -151,6 +151,12 @@
much as possible. The plain text can easily be pasted into a text processor. This is the
default copy format.
+
Assembly Code - Copies raw assembly code from the
+ selected blocks in the Code Browser to the clipboard. Only instruction mnemonics and
+ operands (without markup) are included. The resulting code is suitable for pasting into the
+ Assemble
+ action.
+
Labels and Comments - Copies the labels and
comments from the selected blocks in the Code Browser to the clipboard. These can be pasted
to another part of the program or to another open Code Browser, however, there is no
@@ -167,36 +173,36 @@
Byte String (No Spaces) - This is the same as
the Byte String format, except there are no delimiting spaces between bytes.
-
Data - Copies a the values of all the selected data objects to the clipboard as
- text. This option ignores any compound data objects such as structures, unions, or arrays.
- You can copy data from structures, but you must first open them and select the elements you
- want to copy as a string.
+
Data - Copies a the values of all the selected data objects to the clipboard as
+ text. This option ignores any compound data objects such as structures, unions, or arrays.
+ You can copy data from structures, but you must first open them and select the elements you
+ want to copy as a string.
-
Dereferenced Data - Copies the values of all data pointed to by the selected
- pointers. The contents will be copied to the clipboard as text. If the pointed to data is a
- compound data object such as a structure or array, it is ignored.
+
Dereferenced Data - Copies the values of all data pointed to by the selected
+ pointers. The contents will be copied to the clipboard as text. If the pointed to data is a
+ compound data object such as a structure or array, it is ignored.
-
Python Byte String - Copies the bytes into the Python byte string format, for
- example: b'\x41\xec\x49\x89'.
-
-
Python List String - Copies the bytes into the Python list format, for
- example: [ 0x66, 0x2e, 0x0f, 0x1f, 0x84 ].
-
-
C Array String - Copies the bytes into the C array format, for
- example: { 0x66, 0x2e, 0x0f, 0x1f, 0x84 }.
+
Python Byte String - Copies the bytes into the Python byte string format, for
+ example: b'\x41\xec\x49\x89'.
+
+
Python List String - Copies the bytes into the Python list format, for example:
+ [ 0x66, 0x2e, 0x0f, 0x1f, 0x84 ].
+
+
C Array String - Copies the bytes into the C array format, for example: {
+ 0x66, 0x2e, 0x0f, 0x1f, 0x84 }.
Address - Copies the address at the top of the selection.
-
-
Address w/ Offset - Copies the address at the cursor or each address in the
- current selection. The text is formatted to show the offset from the entry point of the
+
+
Address w/ Offset - Copies the address at the cursor or each address in the
+ current selection. The text is formatted to show the offset from the entry point of the
function, for example: main + 0x2
-
-
Byte Source Offset - Copies the byte source offset from the start of the file for
- each address in the current selection. If the address is not backed by a file,
+
+
Byte Source Offset - Copies the byte source offset from the start of the file
+ for each address in the current selection. If the address is not backed by a file,
<NO_OFFSET> is copied.
-
-
GhidraURL - Creates a GhidraURL for the address under the
- cursor then copies that URL to the clipboard.
+
+
GhidraURL - Creates a GhidraURL for the address under
+ the cursor then copies that URL to the clipboard.
The Code Browser Listing window can paste the following formats:
@@ -239,17 +245,15 @@
Byte String (No Spaces) - This is the same as the Byte String format, except
there are no delimiting spaces between bytes.
-
-
-
Python Byte String - Copies the bytes into the Python byte string format, for
- example: b'\x41\xec\x49\x89'.
-
-
Python List String - Copies the bytes into the Python list format, for
- example: [ 0x66, 0x2e, 0x0f, 0x1f, 0x84 ].
-
-
C Array String - Copies the bytes into the C array format, for
- example: { 0x66, 0x2e, 0x0f, 0x1f, 0x84 }.
-
+
+
Python Byte String - Copies the bytes into the Python byte string format, for
+ example: b'\x41\xec\x49\x89'.
+
+
Python List String - Copies the bytes into the Python list format, for example:
+ [ 0x66, 0x2e, 0x0f, 0x1f, 0x84 ].
+
+
C Array String - Copies the bytes into the C array format, for example: {
+ 0x66, 0x2e, 0x0f, 0x1f, 0x84 }.
The Byte Viewer Bytes In Memory window can paste the following formats: