mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-06 03:50:02 +02:00
MOVE ME to patch and re-describe: GT-3569
This commit is contained in:
parent
0a74b2b063
commit
8c9a727b56
3 changed files with 47 additions and 9 deletions
|
@ -15,13 +15,20 @@
|
||||||
*/
|
*/
|
||||||
package ghidra.app.plugin.assembler.sleigh.parse;
|
package ghidra.app.plugin.assembler.sleigh.parse;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.*;
|
||||||
import java.util.Set;
|
|
||||||
|
import org.apache.commons.collections4.IterableUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An unsuccessful result from parsing
|
* An unsuccessful result from parsing
|
||||||
*/
|
*/
|
||||||
public class AssemblyParseErrorResult extends AssemblyParseResult {
|
public class AssemblyParseErrorResult extends AssemblyParseResult {
|
||||||
|
/**
|
||||||
|
* The maximum number of suggestions to print when describing this error, e.g., when reported in
|
||||||
|
* exception messages.
|
||||||
|
*/
|
||||||
|
private static final int SUGGESTIONS_THRESHOLD = 10;
|
||||||
|
|
||||||
private final String buffer;
|
private final String buffer;
|
||||||
private final Set<String> suggestions;
|
private final Set<String> suggestions;
|
||||||
|
|
||||||
|
@ -40,15 +47,28 @@ public class AssemblyParseErrorResult extends AssemblyParseResult {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a description of the error
|
* Get a description of the error
|
||||||
|
*
|
||||||
* @return a description
|
* @return a description
|
||||||
*/
|
*/
|
||||||
public String describeError() {
|
public String describeError() {
|
||||||
return "Syntax Error: Expected " + suggestions + ". Got " + buffer;
|
Collection<String> truncSuggestions;
|
||||||
|
if (suggestions.size() <= SUGGESTIONS_THRESHOLD) {
|
||||||
|
truncSuggestions = suggestions;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
truncSuggestions = new ArrayList<>();
|
||||||
|
for (String s : IterableUtils.boundedIterable(suggestions, SUGGESTIONS_THRESHOLD)) {
|
||||||
|
truncSuggestions.add(s);
|
||||||
|
}
|
||||||
|
truncSuggestions.add("...");
|
||||||
|
}
|
||||||
|
return "Syntax Error: Expected " + truncSuggestions + ". Got " + buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a set of suggested tokens that would have allowed parsing to continue
|
* Get a set of suggested tokens that would have allowed parsing to continue
|
||||||
* @return the set
|
*
|
||||||
|
* @return the token set
|
||||||
*/
|
*/
|
||||||
public Set<String> getSuggestions() {
|
public Set<String> getSuggestions() {
|
||||||
return Collections.unmodifiableSet(suggestions);
|
return Collections.unmodifiableSet(suggestions);
|
||||||
|
@ -56,7 +76,8 @@ public class AssemblyParseErrorResult extends AssemblyParseResult {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the leftover contents of the input buffer when the error occurred
|
* Get the leftover contents of the input buffer when the error occurred
|
||||||
* @return
|
*
|
||||||
|
* @return the remaining buffer contents
|
||||||
*/
|
*/
|
||||||
public String getBuffer() {
|
public String getBuffer() {
|
||||||
return buffer;
|
return buffer;
|
||||||
|
|
|
@ -202,7 +202,7 @@ public abstract class AbstractAssemblyTest extends AbstractGenericTest {
|
||||||
long addr, String ctxstr) {
|
long addr, String ctxstr) {
|
||||||
final AssemblyPatternBlock ctx =
|
final AssemblyPatternBlock ctx =
|
||||||
(ctxstr == null ? context.getDefault() : AssemblyPatternBlock.fromString(ctxstr))
|
(ctxstr == null ? context.getDefault() : AssemblyPatternBlock.fromString(ctxstr))
|
||||||
.fillMask();
|
.fillMask();
|
||||||
dbg.println("Checking each: " + disassembly + " ctx:" + ctx);
|
dbg.println("Checking each: " + disassembly + " ctx:" + ctx);
|
||||||
boolean gotOne = false;
|
boolean gotOne = false;
|
||||||
boolean failedOne = false;
|
boolean failedOne = false;
|
||||||
|
@ -303,7 +303,7 @@ public abstract class AbstractAssemblyTest extends AbstractGenericTest {
|
||||||
/**
|
/**
|
||||||
* Run a test with the given checks
|
* Run a test with the given checks
|
||||||
*
|
*
|
||||||
* @param assembly the text to assembly
|
* @param assembly the text to assemble
|
||||||
* @param instr an instruction pattern that must appear in the results
|
* @param instr an instruction pattern that must appear in the results
|
||||||
* @param disassembly a set of acceptable disassembly texts
|
* @param disassembly a set of acceptable disassembly texts
|
||||||
* @param addr the address for assembly and disassembly
|
* @param addr the address for assembly and disassembly
|
||||||
|
@ -326,7 +326,7 @@ public abstract class AbstractAssemblyTest extends AbstractGenericTest {
|
||||||
}
|
}
|
||||||
final AssemblyPatternBlock ctx =
|
final AssemblyPatternBlock ctx =
|
||||||
(ctxstr == null ? context.getDefault() : AssemblyPatternBlock.fromString(ctxstr))
|
(ctxstr == null ? context.getDefault() : AssemblyPatternBlock.fromString(ctxstr))
|
||||||
.fillMask();
|
.fillMask();
|
||||||
try {
|
try {
|
||||||
String disstr;
|
String disstr;
|
||||||
PseudoInstruction psins = disassemble(addr, ins.getVals(), ctx.getVals());
|
PseudoInstruction psins = disassemble(addr, ins.getVals(), ctx.getVals());
|
||||||
|
@ -398,7 +398,7 @@ public abstract class AbstractAssemblyTest extends AbstractGenericTest {
|
||||||
/**
|
/**
|
||||||
* Run a test where one result must match a given instruction pattern, and all others must
|
* Run a test where one result must match a given instruction pattern, and all others must
|
||||||
* disassemble exactly to the input
|
* disassemble exactly to the input
|
||||||
*
|
*
|
||||||
* @param assembly the input assembly
|
* @param assembly the input assembly
|
||||||
* @param instr the instruction pattern
|
* @param instr the instruction pattern
|
||||||
* @see AssemblyPatternBlock#fromString(String)
|
* @see AssemblyPatternBlock#fromString(String)
|
||||||
|
|
|
@ -15,6 +15,9 @@
|
||||||
*/
|
*/
|
||||||
package ghidra.app.plugin.assembler.sleigh;
|
package ghidra.app.plugin.assembler.sleigh;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import ghidra.app.plugin.assembler.*;
|
import ghidra.app.plugin.assembler.*;
|
||||||
|
@ -31,6 +34,20 @@ public class x86AssemblyTest extends AbstractAssemblyTest {
|
||||||
return new LanguageID("x86:LE:64:default");
|
return new LanguageID("x86:LE:64:default");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testReasonableErrorMessageLength() throws AssemblySemanticException {
|
||||||
|
Assembler assembler = Assemblers.getAssembler(lang);
|
||||||
|
Address addr = lang.getDefaultSpace().getAddress(DEFAULT_ADDR);
|
||||||
|
try {
|
||||||
|
assembler.assembleLine(addr, "UNLIKELY qword ptr [RAX],RBX");
|
||||||
|
fail(); // The exception must be thrown
|
||||||
|
}
|
||||||
|
catch (AssemblySyntaxException e) {
|
||||||
|
Msg.info(this, "Got expected syntax error: " + e);
|
||||||
|
assertTrue(e.getMessage().length() < 1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAssemble_ADD_m0x12_RAXm_RBX() {
|
public void testAssemble_ADD_m0x12_RAXm_RBX() {
|
||||||
// Again, a little odd. Imm8 does not have the I+R form.
|
// Again, a little odd. Imm8 does not have the I+R form.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue