Merge remote-tracking branch 'origin/GP-0_Dan_testFixes-20220627-1--SQUASHED'

This commit is contained in:
ghidra1 2022-06-27 14:33:06 -04:00
commit 22af19c500
10 changed files with 78 additions and 36 deletions

View File

@ -63,7 +63,8 @@ public abstract class AbstractTracePatchInstructionAction extends PatchInstructi
public void setAddress(Address address) {
super.setAddress(address);
RegisterValue rv = getContextValue(getCodeUnit());
ctx = AssemblyPatternBlock.fromRegisterValue(rv).fillMask();
ctx = rv == null ? AssemblyPatternBlock.nop()
: AssemblyPatternBlock.fromRegisterValue(rv).fillMask();
}
};
}
@ -126,7 +127,9 @@ public abstract class AbstractTracePatchInstructionAction extends PatchInstructi
view.getMemory().setBytes(address, data); // This invalidates cu
AddressSetView set = new AddressSet(address, address.add(data.length - 1));
TraceDisassembleCommand dis = new TraceDisassembleCommand(platform, address, set);
dis.setInitialContext(contextValue);
if (contextValue != null) {
dis.setInitialContext(contextValue);
}
dis.run(tool, view);
}

View File

@ -0,0 +1,27 @@
/* ###
* 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.plugin.core.assembler.AssemblerPluginTestHelper;
import ghidra.app.plugin.core.codebrowser.CodeViewerProvider;
import ghidra.program.model.listing.Program;
public class DebuggerDisassemblerPluginTestHelper extends AssemblerPluginTestHelper {
public DebuggerDisassemblerPluginTestHelper(DebuggerDisassemblerPlugin disassemblerPlugin,
CodeViewerProvider provider, Program program) {
super(disassemblerPlugin.actionPatchInstruction, null, provider, program);
}
}

View File

@ -428,9 +428,8 @@ public class DebuggerDisassemblyTest extends AbstractGhidraHeadedDebuggerGUITest
new ProgramSelection(start, start.addWrap(1)), null);
assertTrue(disassemblerPlugin.actionPatchInstruction.isEnabledForContext(actionContext));
AssemblerPluginTestHelper helper =
new AssemblerPluginTestHelper(disassemblerPlugin.actionPatchInstruction, null,
listingProvider, tb.trace.getProgramView());
DebuggerDisassemblerPluginTestHelper helper = new DebuggerDisassemblerPluginTestHelper(
disassemblerPlugin, listingProvider, tb.trace.getProgramView());
Instruction result = helper.patchInstructionAt(start, "andeq r0,r0,r0", "bx lr");
assertArrayEquals(tb.arr(0x1e, 0xff, 0x2f, 0xe1), result.getBytes());
@ -466,9 +465,8 @@ public class DebuggerDisassemblyTest extends AbstractGhidraHeadedDebuggerGUITest
new ProgramSelection(start, start.addWrap(1)), null);
assertTrue(disassemblerPlugin.actionPatchInstruction.isEnabledForContext(actionContext));
AssemblerPluginTestHelper helper =
new AssemblerPluginTestHelper(disassemblerPlugin.actionPatchInstruction, null,
listingProvider, tb.trace.getProgramView());
DebuggerDisassemblerPluginTestHelper helper = new DebuggerDisassemblerPluginTestHelper(
disassemblerPlugin, listingProvider, tb.trace.getProgramView());
Instruction result = helper.patchInstructionAt(start, "movs r0,r0", "bx lr");
assertArrayEquals(tb.arr(0x70, 0x47), result.getBytes());
@ -502,9 +500,8 @@ public class DebuggerDisassemblyTest extends AbstractGhidraHeadedDebuggerGUITest
new ProgramSelection(start, start.addWrap(1)), null);
assertTrue(disassemblerPlugin.actionPatchInstruction.isEnabledForContext(actionContext));
AssemblerPluginTestHelper helper =
new AssemblerPluginTestHelper(disassemblerPlugin.actionPatchInstruction, null,
listingProvider, tb.trace.getProgramView());
DebuggerDisassemblerPluginTestHelper helper = new DebuggerDisassemblerPluginTestHelper(
disassemblerPlugin, listingProvider, tb.trace.getProgramView());
Instruction result = helper.patchInstructionAt(start, "andeq r0,r0,r0", "bx lr");
assertArrayEquals(tb.arr(0x1e, 0xff, 0x2f, 0xe1), result.getBytes());
@ -543,9 +540,8 @@ public class DebuggerDisassemblyTest extends AbstractGhidraHeadedDebuggerGUITest
new ProgramSelection(start, start.addWrap(1)), null);
assertTrue(disassemblerPlugin.actionPatchInstruction.isEnabledForContext(actionContext));
AssemblerPluginTestHelper helper =
new AssemblerPluginTestHelper(disassemblerPlugin.actionPatchInstruction, null,
listingProvider, tb.trace.getProgramView());
DebuggerDisassemblerPluginTestHelper helper = new DebuggerDisassemblerPluginTestHelper(
disassemblerPlugin, listingProvider, tb.trace.getProgramView());
Instruction result = helper.patchInstructionAt(start, "movs r0,r0", "bx lr");
assertArrayEquals(tb.arr(0x70, 0x47), result.getBytes());

View File

@ -33,6 +33,8 @@ import ghidra.app.plugin.core.assembler.AssemblerPlugin;
import ghidra.app.plugin.core.assembler.AssemblerPluginTestHelper;
import ghidra.app.plugin.core.clipboard.ClipboardPlugin;
import ghidra.app.plugin.core.codebrowser.CodeViewerProvider;
import ghidra.app.plugin.core.debug.disassemble.DebuggerDisassemblerPlugin;
import ghidra.app.plugin.core.debug.disassemble.DebuggerDisassemblerPluginTestHelper;
import ghidra.app.plugin.core.debug.gui.AbstractGhidraHeadedDebuggerGUITest;
import ghidra.app.plugin.core.debug.gui.listing.DebuggerListingPlugin;
import ghidra.app.services.DebuggerStateEditingService;
@ -43,6 +45,7 @@ import ghidra.program.util.ProgramLocation;
import ghidra.trace.database.DBTraceUtils;
import ghidra.trace.model.memory.TraceMemoryFlag;
import ghidra.trace.model.program.TraceVariableSnapProgramView;
import ghidra.util.Swing;
import ghidra.util.database.UndoableTransaction;
/**
@ -58,7 +61,8 @@ public class DebuggerStateEditingPluginIntegrationTest extends AbstractGhidraHea
@Test
public void testPatchInstructionActionInDynamicListingEmu() throws Throwable {
DebuggerListingPlugin listingPlugin = addPlugin(tool, DebuggerListingPlugin.class);
AssemblerPlugin assemblerPlugin = addPlugin(tool, AssemblerPlugin.class);
DebuggerDisassemblerPlugin disassemblerPlugin =
addPlugin(tool, DebuggerDisassemblerPlugin.class);
DebuggerStateEditingPlugin editingPlugin =
addPlugin(tool, DebuggerStateEditingPlugin.class);
DebuggerStateEditingService editingService =
@ -73,13 +77,17 @@ public class DebuggerStateEditingPluginIntegrationTest extends AbstractGhidraHea
tb.trace.getMemoryManager()
.createRegion("Memory[bin:.text]", 0, tb.range(0x00400000, 0x00401000),
Set.of(TraceMemoryFlag.READ, TraceMemoryFlag.EXECUTE));
// Dynamic Patch Instruction requires existing code unit for context
tb.addInstruction(0, tb.addr(0x00400123), tb.host);
}
CodeViewerProvider listingProvider = listingPlugin.getProvider();
AssemblerPluginTestHelper helper =
new AssemblerPluginTestHelper(assemblerPlugin, listingProvider, view);
DebuggerDisassemblerPluginTestHelper helper =
new DebuggerDisassemblerPluginTestHelper(disassemblerPlugin, listingProvider, view);
traceManager.activateTrace(tb.trace);
Swing.runNow(
() -> listingProvider.goTo(view, new ProgramLocation(view, tb.addr(0x00400123))));
waitForSwing();
assertTrue(editingPlugin.actionEditMode.isEnabled());
@ -96,7 +104,8 @@ public class DebuggerStateEditingPluginIntegrationTest extends AbstractGhidraHea
assertTrue(
helper.patchInstructionAction.isAddToPopup(listingProvider.getActionContext(null)));
Instruction ins = helper.patchInstructionAt(tb.addr(0x00400123), "", "imm r0,#1234");
Instruction ins =
helper.patchInstructionAt(tb.addr(0x00400123), "imm r0,#0x0", "imm r0,#1234");
assertEquals(2, ins.getLength());
long snap = traceManager.getCurrent().getViewSnap();

View File

@ -719,14 +719,14 @@ public class AssemblyDualTextField {
* If text parses and assembles, then the completion set will include assembled instruction-byte
* entries. Note that there may still be valid textual completions to continue the instruction.
* The suggestions yielded by all syntax errors are used to create textual completions. If the
* suggestion is prefixed by the buffer where the syntax error ocurred, then, the tail of that
* suggestion is prefixed by the buffer where the syntax error occurred, then, the tail of that
* suggestion is made into a completion entry.
*
* @param text the prefix
* @return the collection of completion items
*/
protected Collection<AssemblyCompletion> computeCompletions(String text) {
final AssemblyPatternBlock ctx = getContext();
final AssemblyPatternBlock ctx = Objects.requireNonNull(getContext());
Set<AssemblyCompletion> result = new TreeSet<>();
Collection<AssemblyParseResult> parses = assembler.parseLine(text);
@ -748,7 +748,7 @@ public class AssemblyDualTextField {
for (AssemblyParseResult parse : parses) {
if (!parse.isError()) {
AssemblyResolutionResults sems =
assembler.resolveTree(parse, address, getContext());
assembler.resolveTree(parse, address, ctx);
for (AssemblyResolution ar : sems) {
if (ar.isError()) {
//result.add(new AssemblyError("", ar.toString()));

View File

@ -45,8 +45,6 @@ public class PatchDataAction extends AbstractPatchAction {
/*test*/ final JTextField input = new JTextField();
private Data data;
public PatchDataAction(Plugin owner) {
this(owner, "Patch Data");
}
@ -119,6 +117,7 @@ public class PatchDataAction extends AbstractPatchAction {
public void accept() {
Program program = getProgram();
Address address = getAddress();
Data data = getData();
DataType dt = data.getBaseDataType();
/**
* Do as much outside the transaction as possible. The tool tends to steal focus away upon

View File

@ -82,7 +82,7 @@ public class AssemblerPluginTestHelper {
AbstractGenericTest.runSwing(() -> {
instructionInput.setText(text);
instructionInput.auto.startCompletion(instructionInput.getOperandsField());
instructionInput.auto.flushUpdates();
instructionInput.auto.updateNow();
});
return AbstractGenericTest.waitForValue(() -> AbstractGenericTest.runSwing(() -> {
List<AssemblyCompletion> suggestions = instructionInput.auto.getSuggestions();

View File

@ -755,6 +755,13 @@ public class TextFieldAutocompleter<T> {
updateManager.flush();
}
/**
* Update the completion list immediately
*/
public void updateNow() {
updateManager.updateNow();
}
/**
* Cause the suggestion at the given index to be selected
*

View File

@ -200,7 +200,8 @@ public abstract class AbstractAssemblyTest extends AbstractGenericTest {
*/
protected void checkAllExact(AssemblyResolutionResults rr, Collection<String> disassembly,
long addr, String ctxstr) {
final AssemblyPatternBlock ctx = (ctxstr == null ? context.getDefault()
Address address = lang.getDefaultSpace().getAddress(addr);
final AssemblyPatternBlock ctx = (ctxstr == null ? context.getDefaultAt(address)
: AssemblyPatternBlock.fromString(ctxstr)).fillMask();
dbg.println("Checking each: " + disassembly + " ctx:" + ctx);
boolean gotOne = false;
@ -316,6 +317,7 @@ public abstract class AbstractAssemblyTest extends AbstractGenericTest {
protected void runTest(String assembly, String instr, Collection<String> disassembly, long addr,
String ctxstr, boolean checkOneCompat, boolean checkAllExact,
boolean checkAllSyntaxErrs, boolean checkAllSemanticErrs) {
Address address = lang.getDefaultSpace().getAddress(addr);
// A sanity check, first
if (instr != null) {
@ -323,9 +325,8 @@ public abstract class AbstractAssemblyTest extends AbstractGenericTest {
if (!ins.isFullMask()) {
throw new RuntimeException("Desired instruction bytes should be fully-defined");
}
final AssemblyPatternBlock ctx =
(ctxstr == null ? context.getDefault() : AssemblyPatternBlock.fromString(ctxstr))
.fillMask();
final AssemblyPatternBlock ctx = (ctxstr == null ? context.getDefaultAt(address)
: AssemblyPatternBlock.fromString(ctxstr)).fillMask();
try {
String disstr;
PseudoInstruction psins = disassemble(addr, ins.getVals(), ctx.getVals());
@ -374,12 +375,11 @@ public abstract class AbstractAssemblyTest extends AbstractGenericTest {
try {
if (ctxstr == null) {
assembler.assembleLine(lang.getDefaultSpace().getAddress(addr), assembly);
assembler.assembleLine(address, assembly);
}
else {
SleighAssembler sas = (SleighAssembler) assembler;
sas.assembleLine(lang.getDefaultSpace().getAddress(addr), assembly,
AssemblyPatternBlock.fromString(ctxstr));
sas.assembleLine(address, assembly, AssemblyPatternBlock.fromString(ctxstr));
}
}
catch (AssemblySemanticException e) {

View File

@ -207,7 +207,8 @@ public abstract class AssemblyTestCase extends AbstractGenericTest {
*/
protected void checkAllExact(AssemblyResolutionResults rr, Collection<String> disassembly,
long addr, String ctxstr) {
final AssemblyPatternBlock ctx = (ctxstr == null ? context.getDefault()
Address address = lang.getDefaultSpace().getAddress(addr);
final AssemblyPatternBlock ctx = (ctxstr == null ? context.getDefaultAt(address)
: AssemblyPatternBlock.fromString(ctxstr)).fillMask();
dbg.println("Checking each: " + disassembly + " ctx:" + ctx);
boolean gotOne = false;
@ -323,6 +324,7 @@ public abstract class AssemblyTestCase extends AbstractGenericTest {
protected void runTest(String assembly, String instr, Collection<String> disassembly, long addr,
String ctxstr, boolean checkOneCompat, boolean checkAllExact,
boolean checkAllSyntaxErrs, boolean checkAllSemanticErrs) {
Address address = lang.getDefaultSpace().getAddress(addr);
// A sanity check, first
if (instr != null) {
@ -330,7 +332,7 @@ public abstract class AssemblyTestCase extends AbstractGenericTest {
if (!ins.isFullMask()) {
throw new RuntimeException("Desired instruction bytes should be fully-defined");
}
final AssemblyPatternBlock ctx = (ctxstr == null ? context.getDefault()
final AssemblyPatternBlock ctx = (ctxstr == null ? context.getDefaultAt(address)
: AssemblyPatternBlock.fromString(ctxstr)).fillMask();
try {
String disstr;
@ -380,12 +382,11 @@ public abstract class AssemblyTestCase extends AbstractGenericTest {
try {
if (ctxstr == null) {
assembler.assembleLine(lang.getDefaultSpace().getAddress(addr), assembly);
assembler.assembleLine(address, assembly);
}
else {
SleighAssembler sas = (SleighAssembler) assembler;
sas.assembleLine(lang.getDefaultSpace().getAddress(addr), assembly,
AssemblyPatternBlock.fromString(ctxstr));
sas.assembleLine(address, assembly, AssemblyPatternBlock.fromString(ctxstr));
}
}
catch (AssemblySemanticException e) {