externals = new ArrayList<>();
- for (Program program : mappings.getOpenMappedProgramsAtSnap(trace, snap)) {
- for (Symbol symbol : program.getSymbolTable().getSymbols(nm)) {
- if (symbol.getSymbolType() != SymbolType.FUNCTION &&
- symbol.getSymbolType() != SymbolType.LABEL) {
- continue;
- }
- SleighSymbol mapped =
- tryMap(nm, trace, snap, program, symbol, symbol.getAddress(), externals);
- if (mapped != null) {
- return mapped;
- }
- mapped = tryExternalLinkage(nm, trace, snap, program, symbol, externals);
- if (mapped != null) {
- return mapped;
+ if (mappings != null) {
+ for (Program program : mappings.getOpenMappedProgramsAtSnap(trace, snap)) {
+ for (Symbol symbol : program.getSymbolTable().getSymbols(nm)) {
+ if (symbol.getSymbolType() != SymbolType.FUNCTION &&
+ symbol.getSymbolType() != SymbolType.LABEL) {
+ continue;
+ }
+ SleighSymbol mapped =
+ tryMap(nm, trace, snap, program, symbol, symbol.getAddress(),
+ externals);
+ if (mapped != null) {
+ return mapped;
+ }
+ mapped = tryExternalLinkage(nm, trace, snap, program, symbol, externals);
+ if (mapped != null) {
+ return mapped;
+ }
}
}
}
@@ -200,13 +282,30 @@ public enum DebuggerPcodeUtils {
* PcodeUseropLibrary)
*/
public static PcodeProgram compileProgram(ServiceProvider provider,
- DebuggerCoordinates coordinates,
- String sourceName, String source, PcodeUseropLibrary> library) {
+ DebuggerCoordinates coordinates, String sourceName, String source,
+ PcodeUseropLibrary> library) {
return SleighProgramCompiler.compileProgram(
- new LabelBoundPcodeParser(provider, coordinates),
+ new LabelBoundPcodeParser(provider, coordinates, null, LitIdMode.NORMAL),
(SleighLanguage) coordinates.getPlatform().getLanguage(), sourceName, source, library);
}
+ /**
+ * Compile the given Sleigh expression into a p-code program, resolving user labels
+ *
+ *
+ * This has the same limitations as
+ * {@link #compileProgram(ServiceProvider, DebuggerCoordinates, String, String, PcodeUseropLibrary)}
+ *
+ * @param mode the mode for parsing integer literals and ids
+ * @see SleighProgramCompiler#compileExpression(PcodeParser, SleighLanguage, String)
+ */
+ public static PcodeExpression compileExpression(ServiceProvider provider,
+ DebuggerCoordinates coordinates, Address current, String source, LitIdMode mode) {
+ return SleighProgramCompiler.compileExpression(
+ new LabelBoundPcodeParser(provider, coordinates, current, mode),
+ (SleighLanguage) coordinates.getPlatform().getLanguage(), source);
+ }
+
/**
* Compile the given Sleigh expression into a p-code program, resolving user labels
*
@@ -217,10 +316,8 @@ public enum DebuggerPcodeUtils {
* @see SleighProgramCompiler#compileExpression(PcodeParser, SleighLanguage, String)
*/
public static PcodeExpression compileExpression(ServiceProvider provider,
- DebuggerCoordinates coordinates, String source) {
- return SleighProgramCompiler.compileExpression(
- new LabelBoundPcodeParser(provider, coordinates),
- (SleighLanguage) coordinates.getPlatform().getLanguage(), source);
+ DebuggerCoordinates coordinates, Address current, String source) {
+ return compileExpression(provider, coordinates, current, source, LitIdMode.NORMAL);
}
/**
diff --git a/Ghidra/Debug/Debugger/src/screen/java/ghidra/app/plugin/core/debug/gui/listing/DebuggerListingPluginScreenShots.java b/Ghidra/Debug/Debugger/src/screen/java/ghidra/app/plugin/core/debug/gui/listing/DebuggerListingPluginScreenShots.java
index 254ed2f8af..fff9798c3e 100644
--- a/Ghidra/Debug/Debugger/src/screen/java/ghidra/app/plugin/core/debug/gui/listing/DebuggerListingPluginScreenShots.java
+++ b/Ghidra/Debug/Debugger/src/screen/java/ghidra/app/plugin/core/debug/gui/listing/DebuggerListingPluginScreenShots.java
@@ -121,9 +121,11 @@ public class DebuggerListingPluginScreenShots extends GhidraScreenShotGenerator
@Test
public void testCaptureDebuggerGoToDialog() throws Throwable {
try (Transaction tx = tb.startTransaction()) {
+ tb.createRootObject();
tb.trace.getTimeManager().createSnapshot("First").getKey();
tb.trace.getMemoryManager()
- .addRegion("bash:.text", Lifespan.nowOn(0), tb.range(0x00400000, 0x0040ffff),
+ .addRegion("Targets[0].Memory[bash:.text]", Lifespan.nowOn(0),
+ tb.range(0x00400000, 0x0040ffff),
Set.of(TraceMemoryFlag.READ, TraceMemoryFlag.EXECUTE));
traceManager.openTrace(tb.trace);
@@ -134,6 +136,7 @@ public class DebuggerListingPluginScreenShots extends GhidraScreenShotGenerator
DebuggerGoToDialog dialog = waitForDialogComponent(DebuggerGoToDialog.class);
dialog.setOffset("RAX");
+ dialog.getComponent().grabFocus();
captureDialog(dialog);
}
}
diff --git a/Ghidra/Features/SystemEmulation/src/main/java/ghidra/pcode/struct/DefaultVar.java b/Ghidra/Features/SystemEmulation/src/main/java/ghidra/pcode/struct/DefaultVar.java
index 5eac1b6d3c..6bedcdea2c 100644
--- a/Ghidra/Features/SystemEmulation/src/main/java/ghidra/pcode/struct/DefaultVar.java
+++ b/Ghidra/Features/SystemEmulation/src/main/java/ghidra/pcode/struct/DefaultVar.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.
@@ -22,6 +22,7 @@ import ghidra.pcodeCPort.slghsymbol.SleighSymbol;
import ghidra.program.model.data.DataType;
import ghidra.program.model.data.DataTypeConflictHandler;
import ghidra.program.model.lang.PcodeParser;
+import ghidra.sleigh.grammar.Location;
class DefaultVar implements LValInternal, Var {
/**
@@ -40,7 +41,7 @@ class DefaultVar implements LValInternal, Var {
@Override
void check(PcodeParser parser, String name) {
// TODO: Also check the type is compatible?
- SleighSymbol symbol = parser.findSymbol(name);
+ SleighSymbol symbol = parser.findSymbol(NO_LOC, name);
if (symbol == null) {
throw new SleighException("Missing symbol '" + name + "'");
}
@@ -50,7 +51,7 @@ class DefaultVar implements LValInternal, Var {
FREE {
@Override
void check(PcodeParser parser, String name) {
- SleighSymbol symbol = parser.findSymbol(name);
+ SleighSymbol symbol = parser.findSymbol(NO_LOC, name);
if (symbol != null) {
throw new SleighException(
"Duplicate symbol '" + name + "': Already defined by the language");
@@ -58,6 +59,8 @@ class DefaultVar implements LValInternal, Var {
}
};
+ static final Location NO_LOC = new Location("??", 0);
+
/**
* Check that the given name obeys the rule
*
diff --git a/Ghidra/Framework/Emulation/src/main/java/ghidra/pcode/exec/SleighProgramCompiler.java b/Ghidra/Framework/Emulation/src/main/java/ghidra/pcode/exec/SleighProgramCompiler.java
index c4aab1246b..5483fd4061 100644
--- a/Ghidra/Framework/Emulation/src/main/java/ghidra/pcode/exec/SleighProgramCompiler.java
+++ b/Ghidra/Framework/Emulation/src/main/java/ghidra/pcode/exec/SleighProgramCompiler.java
@@ -204,14 +204,18 @@ public enum SleighProgramCompiler {
* @return the nil symbol
*/
protected static VarnodeSymbol addNilSymbol(PcodeParser parser) {
- SleighSymbol exists = parser.findSymbol(NIL_SYMBOL_NAME);
+ Location loc = new Location("", 0);
+ SleighSymbol exists = parser.findSymbol(loc, NIL_SYMBOL_NAME);
if (exists != null) {
- // A ClassCastException here indicates a name collision
- return (VarnodeSymbol) exists;
+ if (!(exists instanceof VarnodeSymbol nil)) {
+ throw new AssertionError("Symbol '%s' already exists, but has the wrong type (%s)"
+ .formatted(NIL_SYMBOL_NAME, exists.getClass().getSimpleName()));
+ }
+ return nil;
}
long offset = parser.allocateTemp();
- VarnodeSymbol nil = new VarnodeSymbol(new Location("", 0), NIL_SYMBOL_NAME,
- parser.getUniqueSpace(), offset, 1);
+ VarnodeSymbol nil =
+ new VarnodeSymbol(loc, NIL_SYMBOL_NAME, parser.getUniqueSpace(), offset, 1);
parser.addSymbol(nil);
return nil;
}
diff --git a/Ghidra/Framework/Emulation/src/main/java/ghidra/pcode/exec/SleighUtils.java b/Ghidra/Framework/Emulation/src/main/java/ghidra/pcode/exec/SleighUtils.java
index f72060b79d..7f4265a9e3 100644
--- a/Ghidra/Framework/Emulation/src/main/java/ghidra/pcode/exec/SleighUtils.java
+++ b/Ghidra/Framework/Emulation/src/main/java/ghidra/pcode/exec/SleighUtils.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.
@@ -82,6 +82,14 @@ public enum SleighUtils {
T apply(SleighParser parser) throws RecognitionException;
}
+ public static SleighLexer lexerFor(LitIdMode mode, CharStream input) {
+ return switch (mode) {
+ case NORMAL -> new SleighLexer(input);
+ case HEX -> new SleighLexer(input, new SemanticLexerHex(input));
+ case ID_HEX -> new SleighLexer(input, new SemanticLexerIdHex(input));
+ };
+ }
+
/**
* Parse a non-terminal symbol from the Sleigh semantic grammar
*
@@ -97,10 +105,12 @@ public enum SleighUtils {
* @param nt the function from the parser implementing the non-terminal symbol
* @param text the text to parse
* @param follow a token that would ordinarily follow the non-terminal symbol, or empty for EOF
+ * @param mode the mode for parsing integer literals and ids
* @return the parsed result
*/
public static T parseSleigh(ParseFunction nt,
- String text, String follow) {
+ String text, String follow, LitIdMode mode) {
+
LineArrayListWriter writer = new LineArrayListWriter();
ParsingEnvironment env = new ParsingEnvironment(writer);
@@ -122,7 +132,7 @@ public enum SleighUtils {
env.getLocator().registerLocation(0, new Location("sleigh", 0));
- SleighLexer lex = new SleighLexer(input);
+ SleighLexer lex = lexerFor(mode, input);
lex.setEnv(env);
UnbufferedTokenStream tokens = new UnbufferedTokenStream(lex);
List errors = new ArrayList<>();
@@ -185,6 +195,8 @@ public enum SleighUtils {
}
}
+ validateIntegersObj(t.getTree(), mode, errors);
+
if (!errors.isEmpty()) {
throw new SleighParseError(errors);
}
@@ -192,6 +204,41 @@ public enum SleighUtils {
return t;
}
+ protected static void validateIntegersObj(Object t, LitIdMode mode,
+ List errors) {
+ if (!(t instanceof Tree tree)) {
+ throw new AssertionError();
+ }
+ validateIntegers(tree, mode, errors);
+ }
+
+ protected static void validateIntegers(Tree t, LitIdMode mode,
+ List errors) {
+ switch (t.getType()) {
+ case SleighParser.DEF_INT -> {
+ new RadixBigInteger(null, t.getText(), mode.radix);
+ }
+ case SleighParser.BIN_INT -> {
+ switch (mode) {
+ case NORMAL -> {
+ new RadixBigInteger(null, t.getText().substring(2), 2);
+ }
+ default -> {
+ new RadixBigInteger(null, t.getText(), mode.radix);
+ }
+ }
+ }
+ case SleighParser.HEX_INT -> {
+ new RadixBigInteger(null, t.getText().substring(2), 16);
+ }
+ default -> {
+ for (int i = 0; i < t.getChildCount(); i++) {
+ validateIntegers(t.getChild(i), mode, errors);
+ }
+ }
+ }
+ }
+
/**
* Parse a semantic block, that is a list of Sleigh semantic statements
*
@@ -199,17 +246,64 @@ public enum SleighUtils {
* @return the parse tree
*/
public static Tree parseSleighSemantic(String sleigh) {
- return parseSleigh(SleighParser::semantic, sleigh, "").getTree();
+ return parseSleigh(SleighParser::semantic, sleigh, "", LitIdMode.NORMAL).getTree();
+ }
+
+ /**
+ * Modes for resolving integer literals and labels
+ *
+ * Because Sleigh expressions are often used for address input, we want to allow the default
+ * radix to be 16, rather than requiring the user to type 0x.... This complicates things,
+ * however, in that the literal 'face' could be a label or the integer value in base 16. Parsers
+ * that need to permit this should take this enum as a parameter.
+ */
+ public enum LitIdMode {
+ /**
+ * The normal mode. Un-prefixed integers are in base 10. Labels start with an alpha.
+ */
+ NORMAL("Normal", 10, true),
+ /**
+ * Hex mode preferring integer values. Un-prefixed are in base 16. Any literal that could be
+ * a hex integer is taken for its integer value. '0b'-prefixed literals are no longer
+ * allowed. They are instead taken as hex literals. Identifiers/labels consisting only of
+ * hex digits are also taken as hex literals. Note that explicit prefixes are still allowed,
+ * except for '0b' (binary). Also note that only the "value" portion of a literal is
+ * implicitly hex. The size, bitranges, etc., are still base 10 by default.
+ */
+ HEX("Hex", 16, false),
+ /**
+ * Hex mode preferring ids. This works the same as {@link #HEX}, except that a literal that
+ * could be an identifier/label is taken as that id instead of its integer value. To avoid
+ * interpreting a value as a label, prefix it with a 0.
+ */
+ ID_HEX("Hex, prefer ids", 16, true);
+
+ public static final List VALUES = List.of(values());
+
+ public final String description;
+ public final int radix;
+ public final boolean preferId;
+
+ private LitIdMode(String description, int radix, boolean preferId) {
+ this.description = description;
+ this.radix = radix;
+ this.preferId = preferId;
+ }
}
/**
* Parse a semantic expression
*
* @param expression the expression as a string
+ * @param mode the mode for parsing integer literals and ids
* @return the parse tree
*/
+ public static Tree parseSleighExpression(String expression, LitIdMode mode) {
+ return parseSleigh(SleighParser::expr, expression, ";", mode).getTree();
+ }
+
public static Tree parseSleighExpression(String expression) {
- return parseSleigh(SleighParser::expr, expression, ";").getTree();
+ return parseSleighExpression(expression, LitIdMode.NORMAL);
}
/**
@@ -308,8 +402,8 @@ public enum SleighUtils {
match(tree, SleighParser.OP_DEREFERENCE, onSpace, onOffset);
return;
case SleighParser.OP_BIN_CONSTANT:
- case SleighParser.OP_DEC_CONSTANT:
case SleighParser.OP_HEX_CONSTANT:
+ case SleighParser.OP_DEF_CONSTANT:
match(tree, SleighParser.OP_DEREFERENCE, onSize, onOffset);
return;
default:
@@ -431,8 +525,7 @@ public enum SleighUtils {
}
}
- public record AddressOf(String space, Tree offset) {
- }
+ public record AddressOf(String space, Tree offset) {}
public static AddressOf recoverAddressOf(String defaultSpace, Tree tree) {
var l = new Object() {
@@ -489,15 +582,15 @@ public enum SleighUtils {
private static void generateSleighExpression(Tree tree, StringBuilder sb) {
switch (tree.getType()) {
case SleighParser.BIN_INT:
- case SleighParser.DEC_INT:
case SleighParser.HEX_INT:
+ case SleighParser.DEF_INT:
case SleighParser.IDENTIFIER:
sb.append(tree.getText());
break;
case SleighParser.OP_BIN_CONSTANT:
- case SleighParser.OP_DEC_CONSTANT:
case SleighParser.OP_HEX_CONSTANT:
+ case SleighParser.OP_DEF_CONSTANT:
case SleighParser.OP_IDENTIFIER:
generateSleighExpression(tree.getChild(0), sb);
break;
@@ -655,8 +748,8 @@ public enum SleighUtils {
generateSleighExpression(tree.getChild(1), sb);
break;
case SleighParser.OP_BIN_CONSTANT:
- case SleighParser.OP_DEC_CONSTANT:
case SleighParser.OP_HEX_CONSTANT:
+ case SleighParser.OP_DEF_CONSTANT:
sb.append("*:");
generateSleighExpression(child0, sb);
sb.append(" ");
diff --git a/Ghidra/Framework/Emulation/src/test/java/ghidra/pcode/exec/SleighUtilsTest.java b/Ghidra/Framework/Emulation/src/test/java/ghidra/pcode/exec/SleighUtilsTest.java
index 43fb5a60cd..a0ea00277c 100644
--- a/Ghidra/Framework/Emulation/src/test/java/ghidra/pcode/exec/SleighUtilsTest.java
+++ b/Ghidra/Framework/Emulation/src/test/java/ghidra/pcode/exec/SleighUtilsTest.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.
@@ -21,8 +21,7 @@ import org.antlr.runtime.RecognitionException;
import org.antlr.runtime.tree.Tree;
import org.junit.Test;
-import ghidra.pcode.exec.SleighUtils.AddressOf;
-import ghidra.pcode.exec.SleighUtils.SleighParseError;
+import ghidra.pcode.exec.SleighUtils.*;
public class SleighUtilsTest {
@Test
@@ -35,7 +34,7 @@ public class SleighUtilsTest {
""";
Tree tree = SleighUtils.parseSleighSemantic(mySleigh);
assertEquals(
- "(OP_SEMANTIC (if (! ((...) (== (IDENTIFIER RAX) (DEC_INT 0)))) (goto " +
+ "(OP_SEMANTIC (if (! ((...) (== (IDENTIFIER RAX) (DEF_INT 0)))) (goto " +
"(OP_JUMPDEST_LABEL (< (IDENTIFIER L1))))) (OP_APPLY (IDENTIFIER emu_swi)) " +
"(< (IDENTIFIER L1)) (OP_APPLY (IDENTIFIER emu_exec_decoded)))",
tree.toStringTree());
@@ -262,10 +261,18 @@ public class SleighUtilsTest {
@Test
public void testParseSleighExpression() throws RecognitionException {
- assertEquals("(|| (== (IDENTIFIER RAX) (DEC_INT 0)) (== (IDENTIFIER RBX) (DEC_INT 7)))",
+ assertEquals("(|| (== (IDENTIFIER RAX) (DEF_INT 0)) (== (IDENTIFIER RBX) (DEF_INT 7)))",
SleighUtils.parseSleighExpression("RAX == 0 || RBX == 7").toStringTree());
}
+ @Test
+ public void testParseSleighExpressionHex() throws RecognitionException {
+ assertEquals("(DEF_INT 0afeface)",
+ SleighUtils.parseSleighExpression("0afeface", LitIdMode.HEX).toStringTree());
+ assertEquals("(DEF_INT cafeface)",
+ SleighUtils.parseSleighExpression("cafeface", LitIdMode.HEX).toStringTree());
+ }
+
@Test
public void testParseSleighExpressionErr() throws RecognitionException {
try {
diff --git a/Ghidra/Framework/SoftwareModeling/build.gradle b/Ghidra/Framework/SoftwareModeling/build.gradle
index 36187041b6..ee2450f258 100644
--- a/Ghidra/Framework/SoftwareModeling/build.gradle
+++ b/Ghidra/Framework/SoftwareModeling/build.gradle
@@ -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.
@@ -60,6 +60,8 @@ generateGrammarSource {
include "ghidra/sleigh/grammar/BaseLexer.g"
include "ghidra/sleigh/grammar/DisplayLexer.g"
include "ghidra/sleigh/grammar/SemanticLexer.g"
+ include "ghidra/sleigh/grammar/SemanticLexerHex.g"
+ include "ghidra/sleigh/grammar/SemanticLexerIdHex.g"
// This is the root parser, it will import its children without building them individually.
include "ghidra/sleigh/grammar/SleighParser.g"
@@ -72,15 +74,13 @@ generateGrammarSource {
// README: See src/main/antlr/ghidra/sleigh/grammar/README.txt for an explanation of this.
doFirst {
- // Ensure that SleighLexar.tokens is rebuilt by removing it if any of the
- // contributing grammar files have changed. Antlr plugin does not know
- // about the SleighLexar.tokens dependency on changes to BaseLexer.g,
- // DisplayLexer.g or SemanticLexer.g
- delete file("$buildDir/${genSrcDir}/ghidra/sleigh/grammar/SleighLexer.tokens")
+ // The ANTLR plugin's incremental compilation seems to cause issues, so clean out token
+ // files before any attempted compilation.
+ delete file("$buildDir/${genSrcDir}/ghidra/sleigh/grammar/*.tokens")
}
doLast {
- // SleighLexar.g is only needed to produce SleighLexar.tokens.
+ // SleighLexer.g is only needed to produce SleighLexer.tokens.
// Remove its generated java artifacts which may conflict
delete fileTree("$buildDir/${genSrcDir}/ghidra/sleigh/grammar") {
include "SleighLexer*.java"
diff --git a/Ghidra/Framework/SoftwareModeling/certification.manifest b/Ghidra/Framework/SoftwareModeling/certification.manifest
index 1a9c839cf4..003d234b55 100644
--- a/Ghidra/Framework/SoftwareModeling/certification.manifest
+++ b/Ghidra/Framework/SoftwareModeling/certification.manifest
@@ -20,6 +20,8 @@ src/main/antlr/ghidra/sleigh/grammar/DisplayLexer.g||GHIDRA||||END|
src/main/antlr/ghidra/sleigh/grammar/DisplayParser.g||GHIDRA||||END|
src/main/antlr/ghidra/sleigh/grammar/README.txt||GHIDRA||||END|
src/main/antlr/ghidra/sleigh/grammar/SemanticLexer.g||GHIDRA||||END|
+src/main/antlr/ghidra/sleigh/grammar/SemanticLexerHex.g||GHIDRA||||END|
+src/main/antlr/ghidra/sleigh/grammar/SemanticLexerIdHex.g||GHIDRA||||END|
src/main/antlr/ghidra/sleigh/grammar/SemanticParser.g||GHIDRA||||END|
src/main/antlr/ghidra/sleigh/grammar/SleighCompiler.g||GHIDRA||||END|
src/main/antlr/ghidra/sleigh/grammar/SleighEcho.g||GHIDRA||||END|
diff --git a/Ghidra/Framework/SoftwareModeling/src/main/antlr/ghidra/sleigh/grammar/BaseLexer.g b/Ghidra/Framework/SoftwareModeling/src/main/antlr/ghidra/sleigh/grammar/BaseLexer.g
index aaec246069..076578bacf 100644
--- a/Ghidra/Framework/SoftwareModeling/src/main/antlr/ghidra/sleigh/grammar/BaseLexer.g
+++ b/Ghidra/Framework/SoftwareModeling/src/main/antlr/ghidra/sleigh/grammar/BaseLexer.g
@@ -33,6 +33,7 @@ tokens {
OP_DEC;
OP_DECLARATIVE_SIZE;
OP_DEC_CONSTANT;
+ OP_DEF_CONSTANT;
OP_DEFAULT;
OP_DEREFERENCE;
OP_DISPLAY;
@@ -298,16 +299,20 @@ HEXDIGIT
| 'A'..'F'
;
+BIN_INT
+ : '0b' (BINDIGIT)+
+ ;
+
DEC_INT
- : DIGIT+
+ : '0n' (DIGIT)+
;
HEX_INT
: '0x' (HEXDIGIT)+
;
-BIN_INT
- : '0b' (BINDIGIT)+
+DEF_INT
+ : DIGIT+
;
fragment
diff --git a/Ghidra/Framework/SoftwareModeling/src/main/antlr/ghidra/sleigh/grammar/DisplayParser.g b/Ghidra/Framework/SoftwareModeling/src/main/antlr/ghidra/sleigh/grammar/DisplayParser.g
index 26f39cbdb0..5c733ec236 100644
--- a/Ghidra/Framework/SoftwareModeling/src/main/antlr/ghidra/sleigh/grammar/DisplayParser.g
+++ b/Ghidra/Framework/SoftwareModeling/src/main/antlr/ghidra/sleigh/grammar/DisplayParser.g
@@ -78,7 +78,7 @@ special
| lc=SPEC_OR -> ^(OP_STRING[$lc, "SPEC_OR"] SPEC_OR)
| lc=SPEC_AND -> ^(OP_STRING[$lc, "SPEC_AND"] SPEC_AND)
| lc=SPEC_XOR -> ^(OP_STRING[$lc, "SPEC_XOR"] SPEC_XOR)
- | lc=DEC_INT -> ^(OP_STRING[$lc, "DEC_INT"] DEC_INT)
+ | lc=DEF_INT -> ^(OP_STRING[$lc, "DEF_INT"] DEF_INT)
| lc=HEX_INT -> ^(OP_STRING[$lc, "HEX_INT"] HEX_INT)
| lc=BIN_INT -> ^(OP_STRING[$lc, "BIN_INT"] BIN_INT)
;
diff --git a/Ghidra/Framework/SoftwareModeling/src/main/antlr/ghidra/sleigh/grammar/SemanticLexerHex.g b/Ghidra/Framework/SoftwareModeling/src/main/antlr/ghidra/sleigh/grammar/SemanticLexerHex.g
new file mode 100644
index 0000000000..7426915983
--- /dev/null
+++ b/Ghidra/Framework/SoftwareModeling/src/main/antlr/ghidra/sleigh/grammar/SemanticLexerHex.g
@@ -0,0 +1,30 @@
+lexer grammar SemanticLexerHex;
+
+options {
+ superClass = AbstractSleighLexer;
+ tokenVocab = SleighLexer;
+}
+
+import SemanticLexer;
+
+@members {
+ @Override
+ public void setEnv(ParsingEnvironment env) {
+ super.setEnv(env);
+ gSemanticLexer.setEnv(env);
+ // HACK to fix ANTLR?
+ gBaseLexer = gSemanticLexer.gBaseLexer;
+ }
+}
+
+DEF_INT
+ : HEXDIGIT+
+ ;
+
+IDENTIFIER
+ : ALPHAUP (ALPHAUP | DIGIT)*
+ ;
+
+BIN_INT
+ : '********THIS_SHOULD_NEVER_MATCH********'
+ ;
diff --git a/Ghidra/Framework/SoftwareModeling/src/main/antlr/ghidra/sleigh/grammar/SemanticLexerIdHex.g b/Ghidra/Framework/SoftwareModeling/src/main/antlr/ghidra/sleigh/grammar/SemanticLexerIdHex.g
new file mode 100644
index 0000000000..02b2ab98cf
--- /dev/null
+++ b/Ghidra/Framework/SoftwareModeling/src/main/antlr/ghidra/sleigh/grammar/SemanticLexerIdHex.g
@@ -0,0 +1,30 @@
+lexer grammar SemanticLexerIdHex;
+
+options {
+ superClass = AbstractSleighLexer;
+ tokenVocab = SleighLexer;
+}
+
+import SemanticLexer;
+
+@members {
+ @Override
+ public void setEnv(ParsingEnvironment env) {
+ super.setEnv(env);
+ gSemanticLexer.setEnv(env);
+ // HACK to fix ANTLR?
+ gBaseLexer = gSemanticLexer.gBaseLexer;
+ }
+}
+
+IDENTIFIER
+ : ALPHAUP (ALPHAUP | DIGIT)*
+ ;
+
+DEF_INT
+ : DIGIT (HEXDIGIT)*
+ ;
+
+BIN_INT
+ : '********THIS_SHOULD_NEVER_MATCH********'
+ ;
diff --git a/Ghidra/Framework/SoftwareModeling/src/main/antlr/ghidra/sleigh/grammar/SemanticParser.g b/Ghidra/Framework/SoftwareModeling/src/main/antlr/ghidra/sleigh/grammar/SemanticParser.g
index 795bd45200..a5ab9a5a31 100644
--- a/Ghidra/Framework/SoftwareModeling/src/main/antlr/ghidra/sleigh/grammar/SemanticParser.g
+++ b/Ghidra/Framework/SoftwareModeling/src/main/antlr/ghidra/sleigh/grammar/SemanticParser.g
@@ -324,9 +324,9 @@ expr_term
;
varnode
- : integer
+ : int_lit
| identifier
- | integer lc=COLON constant -> ^(OP_TRUNCATION_SIZE[$lc] integer constant)
+ | int_lit lc=COLON constant -> ^(OP_TRUNCATION_SIZE[$lc] int_lit constant)
| identifier lc=COLON constant -> ^(OP_BITRANGE2[$lc] identifier constant)
| lc=AMPERSAND fp=COLON constant varnode -> ^(OP_ADDRESS_OF[$lc] ^(OP_SIZING_SIZE[$fp] constant) varnode)
| lc=AMPERSAND varnode -> ^(OP_ADDRESS_OF[$lc] varnode)
@@ -336,8 +336,15 @@ constant
: integer
;
-integer
+int_lit
: lc=HEX_INT -> ^(OP_HEX_CONSTANT[$lc, "HEX_INT"] HEX_INT)
| lc=DEC_INT -> ^(OP_DEC_CONSTANT[$lc, "DEC_INT"] DEC_INT)
| lc=BIN_INT -> ^(OP_BIN_CONSTANT[$lc, "BIN_INT"] BIN_INT)
+ | lc=DEF_INT -> ^(OP_DEF_CONSTANT[$lc, "DEF_INT"] DEF_INT)
+ ;
+
+integer
+ : lc=HEX_INT -> ^(OP_HEX_CONSTANT[$lc, "HEX_INT"] HEX_INT)
+ | lc=BIN_INT -> ^(OP_BIN_CONSTANT[$lc, "BIN_INT"] BIN_INT)
+ | lc=DEF_INT -> ^(OP_DEF_CONSTANT[$lc, "DEF_INT"] DEF_INT)
;
diff --git a/Ghidra/Framework/SoftwareModeling/src/main/antlr/ghidra/sleigh/grammar/SleighCompiler.g b/Ghidra/Framework/SoftwareModeling/src/main/antlr/ghidra/sleigh/grammar/SleighCompiler.g
index b28cdb24e0..af4d54e70d 100644
--- a/Ghidra/Framework/SoftwareModeling/src/main/antlr/ghidra/sleigh/grammar/SleighCompiler.g
+++ b/Ghidra/Framework/SoftwareModeling/src/main/antlr/ghidra/sleigh/grammar/SleighCompiler.g
@@ -1,8 +1,9 @@
tree grammar SleighCompiler;
options {
- ASTLabelType=CommonTree;
- tokenVocab=SleighLexer;
+ superClass = AbstractSleighCompiler;
+ ASTLabelType = CommonTree;
+ tokenVocab = SleighLexer;
}
scope Jump {
@@ -36,134 +37,6 @@ scope Block {
import org.antlr.runtime.tree.*;
}
-@members {
- private static final BigInteger MAX_ULONG = new BigInteger("ffffffffffffffff", 16);
- private static final BigInteger MIN_SLONG = new BigInteger("-8000000000000000", 16);
- private static final BigInteger MAX_UINT = new BigInteger("ffffffff", 16);
-
- private ParsingEnvironment env = null;
- private SleighCompile sc = null;
- private PcodeCompile pcode = null;
-
- private void reportError(Location loc, String msg) {
- if (pcode != null) {
- pcode.reportError(loc, msg);
- }
- else {
- sc.reportError(loc, msg);
- }
- }
-
- private void reportWarning(Location loc, String msg) {
- if (pcode != null) {
- pcode.reportWarning(loc, msg);
- }
- else {
- sc.reportWarning(loc, msg);
- }
- }
-
- private void check(RadixBigInteger rbi) {
- if (rbi.bitLength() > 64) {
- reportError(rbi.location, "Integer representation exceeds Java long (" + rbi + ")");
- }
- }
-
- private long toSLong(RadixBigInteger bi) {
- try {
- return bi.longValueExact();
- }
- catch (ArithmeticException e) {
- reportError(bi.location, "Integer cannot be represented as signed long: " + bi);
- return bi.longValue();
- }
- }
-
- private long toULong(RadixBigInteger bi) {
- if (bi.compareTo(MAX_ULONG) > 0 || bi.signum() < 0) {
- reportError(bi.location, "Integer cannot be represented as unsigned long: " + bi);
- }
- return bi.longValue();
- }
-
- private long toLong(RadixBigInteger bi) {
- if (bi.compareTo(MAX_ULONG) > 0 || bi.compareTo(MIN_SLONG) < 0) {
- reportError(bi.location, "Integer cannot be represented as long: " + bi);
- }
- return bi.longValue();
- }
-
- private int toUInt(RadixBigInteger bi) {
- if (bi.compareTo(MAX_UINT) > 0 || bi.signum() < 0) {
- reportError(bi.location, "Integer cannot be represented as unsigned int: " + bi);
- }
- return bi.intValue();
- }
-
- private void redefinedError(SleighSymbol sym, Tree t, String what) {
- String msg = "symbol '" + sym.getName() + "' (from " + sym.getLocation() + ") redefined as " + what;
- reportError(find(t), msg);
- }
-
- private void wildcardError(Tree t, String what) {
- String msg = "wildcard (_) not allowed in " + what;
- reportError(find(t), msg);
- }
-
- private void wrongSymbolTypeError(SleighSymbol sym, Location where, String type, String purpose) {
- String msg = sym.getType() + " '" + sym + "' (defined at " + sym.getLocation() + ") is wrong type (should be " + type + ") in " + purpose;
- reportError(where, msg);
- }
-
- private void undeclaredSymbolError(SleighSymbol sym, Location where, String purpose) {
- String msg = "'" + sym + "' (used in " + purpose + ") is not declared in the pattern list";
- reportError(where, msg);
- }
-
- private void unknownSymbolError(String text, Location loc, String type, String purpose) {
- String msg = "unknown " + type + " '" + text + "' in " + purpose;
- reportError(loc, msg);
- }
-
- private void invalidDynamicTargetError(Location loc, String purpose) {
- String msg = "invalid dynamic target used in " + purpose;
- reportError(loc, msg);
- }
-
- private Location find(Tree t) {
- return env.getLocator().getLocation(t.getLine());
- }
-
- private SubtableSymbol findOrNewTable(Location loc, String name) {
- SleighSymbol sym = sc.findSymbol(name);
- if (sym == null) {
- SubtableSymbol ss = sc.newTable(loc, name);
- return ss;
- } else if(sym.getType() != symbol_type.subtable_symbol) {
- wrongSymbolTypeError(sym, loc, "subtable", "subconstructor");
- return null;
- } else {
- return (SubtableSymbol) sym;
- }
- }
-
- public String getErrorMessage(RecognitionException e, String[] tokenNames) {
- return env.getParserErrorMessage(e, tokenNames);
- }
-
- public String getTokenErrorDisplay(Token t) {
- return env.getTokenErrorDisplay(t);
- }
-
- public String getErrorHeader(RecognitionException e) {
- return env.getErrorHeader(e);
- }
-
- void bail(String msg) {
- throw new BailoutException(msg);
- }
-}
-
root[ParsingEnvironment pe, SleighCompile sc] returns [int errors]
@init {
this.env = pe;
@@ -217,21 +90,25 @@ tokendef
SleighSymbol sym = sc.findSymbol($n.value.getText());
if (sym != null) {
redefinedError(sym, n, "token");
- } else {
- $tokendef::tokenSymbol = sc.defineToken(find(n), $n.value.getText(), toLong($i.value), 0);
+ }
+ else {
+ $tokendef::tokenSymbol = sc.defineToken(find(n), $n.value.getText(),
+ toLong($i.value), 0);
}
}
} fielddefs)
- | ^(OP_TOKEN_ENDIAN n=specific_identifier["token definition"] i=integer s=endian {
+ | ^(OP_TOKEN_ENDIAN n=specific_identifier["token definition"] i=integer s=endian {
if (n != null) {
- SleighSymbol sym = sc.findSymbol($n.value.getText());
- if (sym != null) {
- redefinedError(sym, n, "token");
- } else {
- $tokendef::tokenSymbol = sc.defineToken(find(n), $n.value.getText(), toLong($i.value), $s.value ==0 ? -1 : 1);
- }
+ SleighSymbol sym = sc.findSymbol($n.value.getText());
+ if (sym != null) {
+ redefinedError(sym, n, "token");
+ }
+ else {
+ $tokendef::tokenSymbol = sc.defineToken(find(n), $n.value.getText(),
+ toLong($i.value), $s.value ==0 ? -1 : 1);
+ }
}
- } fielddefs)
+ } fielddefs)
;
fielddefs
@@ -247,15 +124,19 @@ fielddef
}
: ^(t=OP_FIELDDEF n=unbound_identifier["field"] s=integer e=integer {
if (n != null) {
- $fielddef::fieldQuality = new FieldQuality($n.value.getText(), find($t), toULong($s.value), toULong($e.value));
+ $fielddef::fieldQuality = new FieldQuality($n.value.getText(), find($t),
+ toULong($s.value), toULong($e.value));
}
} fieldmods) {
if ($fielddef.size() > 0 && $fielddef::fieldQuality != null) {
if ($tokendef.size() > 0 && $tokendef::tokenSymbol != null) {
sc.addTokenField(find(n), $tokendef::tokenSymbol, $fielddef::fieldQuality);
- } else if ($contextdef.size() > 0 && $contextdef::varnode != null) {
- if (!sc.addContextField(find(n), $contextdef::varnode, $fielddef::fieldQuality)) {
- reportError(find($t), "all context definitions must come before constructors");
+ }
+ else if ($contextdef.size() > 0 && $contextdef::varnode != null) {
+ if (!sc.addContextField(find(n), $contextdef::varnode,
+ $fielddef::fieldQuality)) {
+ reportError(find($t),
+ "all context definitions must come before constructors");
}
}
}
@@ -268,11 +149,11 @@ fieldmods
;
fieldmod
- : OP_SIGNED { if ($fielddef::fieldQuality != null) $fielddef::fieldQuality.signext = true; }
- | OP_NOFLOW { if ($fielddef::fieldQuality != null) $fielddef::fieldQuality.flow = false; }
- | OP_HEX { if ($fielddef::fieldQuality != null) $fielddef::fieldQuality.hex = true; }
- | OP_DEC { if ($fielddef::fieldQuality != null) $fielddef::fieldQuality.hex = false; }
- ;
+ : OP_SIGNED { if ($fielddef::fieldQuality != null) $fielddef::fieldQuality.signext = true; }
+ | OP_NOFLOW { if ($fielddef::fieldQuality != null) $fielddef::fieldQuality.flow = false; }
+ | OP_HEX { if ($fielddef::fieldQuality != null) $fielddef::fieldQuality.hex = true; }
+ | OP_DEC { if ($fielddef::fieldQuality != null) $fielddef::fieldQuality.hex = false; }
+ ;
specific_identifier[String purpose] returns [Tree value]
: ^(OP_IDENTIFIER s=.) { $value = $s; }
@@ -284,12 +165,15 @@ specific_identifier[String purpose] returns [Tree value]
unbound_identifier[String purpose] returns [Tree value]
: ^(OP_IDENTIFIER s=.) {
- // use PcodeCompile for symbol table while parsing pcode
- SleighSymbol sym = pcode != null ? pcode.findSymbol($s.getText()) : sc.findSymbol($s.getText());
+ // use PcodeCompile for symbol table while parsing pcode
+ SleighSymbol sym = pcode != null
+ ? pcode.findSymbol(find($s), $s.getText())
+ : sc.findSymbol($s.getText());
if (sym != null) {
redefinedError(sym, $s, purpose);
$value = null;
- } else {
+ }
+ else {
$value = $s;
}
}
@@ -304,9 +188,11 @@ varnode_symbol[String purpose, boolean noWildcards] returns [VarnodeSymbol symbo
SleighSymbol sym = sc.findSymbol($s.getText());
if (sym == null) {
unknownSymbolError($s.getText(), find($s), "varnode", purpose);
- } else if(sym.getType() != symbol_type.varnode_symbol) {
+ }
+ else if (sym.getType() != symbol_type.varnode_symbol) {
wrongSymbolTypeError(sym, find($s), "varnode", purpose);
- } else {
+ }
+ else {
$symbol = (VarnodeSymbol) sym;
}
}
@@ -323,10 +209,12 @@ value_symbol[String purpose] returns [Pair symbol]
SleighSymbol sym = sc.findSymbol($s.getText());
if (sym == null) {
unknownSymbolError($s.getText(), find($s), "value or context", purpose);
- } else if(sym.getType() == symbol_type.value_symbol
- || sym.getType() == symbol_type.context_symbol) {
- $symbol = new Pair((ValueSymbol) sym, find($s));
- } else {
+ }
+ else if (sym.getType() == symbol_type.value_symbol ||
+ sym.getType() == symbol_type.context_symbol) {
+ $symbol = new Pair<>((ValueSymbol) sym, find($s));
+ }
+ else {
wrongSymbolTypeError(sym, find($s), "value or context", purpose);
}
}
@@ -338,12 +226,14 @@ value_symbol[String purpose] returns [Pair symbol]
operand_symbol[String purpose] returns [OperandSymbol symbol]
: ^(OP_IDENTIFIER s=.) {
- SleighSymbol sym = pcode.findSymbol($s.getText());
+ SleighSymbol sym = pcode.findSymbol(find($s), $s.getText());
if (sym == null) {
unknownSymbolError($s.getText(), find($s), "operand", purpose);
- } else if(sym.getType() != symbol_type.operand_symbol) {
+ }
+ else if (sym.getType() != symbol_type.operand_symbol) {
wrongSymbolTypeError(sym, find($s), "operand", purpose);
- } else {
+ }
+ else {
$symbol = (OperandSymbol) sym;
}
}
@@ -356,12 +246,16 @@ operand_symbol[String purpose] returns [OperandSymbol symbol]
space_symbol[String purpose] returns [SpaceSymbol symbol]
: ^(OP_IDENTIFIER s=.) {
// use PcodeCompile for symbol table while parsing pcode
- SleighSymbol sym = pcode != null ? pcode.findSymbol($s.getText()) : sc.findSymbol($s.getText());
+ SleighSymbol sym = pcode != null
+ ? pcode.findSymbol(find($s), $s.getText())
+ : sc.findSymbol($s.getText());
if (sym == null) {
unknownSymbolError($s.getText(), find($s), "space", purpose);
- } else if(sym.getType() != symbol_type.space_symbol) {
+ }
+ else if (sym.getType() != symbol_type.space_symbol) {
wrongSymbolTypeError(sym, find($s), "space", purpose);
- } else {
+ }
+ else {
$symbol = (SpaceSymbol) sym;
}
}
@@ -373,19 +267,22 @@ space_symbol[String purpose] returns [SpaceSymbol symbol]
specific_symbol[String purpose] returns [SpecificSymbol symbol]
: ^(OP_IDENTIFIER s=.) {
- SleighSymbol sym = pcode.findSymbol($s.getText());
+ SleighSymbol sym = pcode.findSymbol(find($s), $s.getText());
if (sym == null) {
- unknownSymbolError($s.getText(), find($s), "start, end, next2, operand, epsilon, or varnode", purpose);
- } else if(sym.getType() != symbol_type.start_symbol
- && sym.getType() != symbol_type.end_symbol
- && sym.getType() != symbol_type.next2_symbol
- && sym.getType() != symbol_type.flowdest_symbol
- && sym.getType() != symbol_type.flowref_symbol
- && sym.getType() != symbol_type.operand_symbol
- && sym.getType() != symbol_type.epsilon_symbol
- && sym.getType() != symbol_type.varnode_symbol) {
+ unknownSymbolError($s.getText(), find($s),
+ "start, end, next2, operand, epsilon, or varnode", purpose);
+ }
+ else if (sym.getType() != symbol_type.start_symbol &&
+ sym.getType() != symbol_type.end_symbol &&
+ sym.getType() != symbol_type.next2_symbol &&
+ sym.getType() != symbol_type.flowdest_symbol &&
+ sym.getType() != symbol_type.flowref_symbol &&
+ sym.getType() != symbol_type.operand_symbol &&
+ sym.getType() != symbol_type.epsilon_symbol &&
+ sym.getType() != symbol_type.varnode_symbol) {
undeclaredSymbolError(sym, find($s), purpose);
- } else {
+ }
+ else {
$symbol = (SpecificSymbol) sym;
}
}
@@ -400,13 +297,15 @@ family_symbol[String purpose] returns [FamilySymbol symbol]
SleighSymbol sym = sc.findSymbol($s.getText());
if (sym == null) {
unknownSymbolError($s.getText(), find($s), "family", purpose);
- } else if(sym.getType() != symbol_type.value_symbol
- && sym.getType() != symbol_type.valuemap_symbol
- && sym.getType() != symbol_type.context_symbol
- && sym.getType() != symbol_type.name_symbol
- && sym.getType() != symbol_type.varnodelist_symbol) {
+ }
+ else if (sym.getType() != symbol_type.value_symbol &&
+ sym.getType() != symbol_type.valuemap_symbol &&
+ sym.getType() != symbol_type.context_symbol &&
+ sym.getType() != symbol_type.name_symbol &&
+ sym.getType() != symbol_type.varnodelist_symbol) {
wrongSymbolTypeError(sym, find($s), "family", purpose);
- } else {
+ }
+ else {
$symbol = (FamilySymbol) sym;
}
}
@@ -468,7 +367,8 @@ typemod
try {
space_class type = space_class.valueOf(typeName);
$spacedef::quality.type = type;
- } catch(IllegalArgumentException e) {
+ }
+ catch(IllegalArgumentException e) {
reportError(find(n), "invalid space type '" + typeName + "'");
}
}
@@ -488,7 +388,8 @@ wordsizemod
;
varnodedef
- : ^(OP_VARNODE s=space_symbol["varnode definition"] offset=integer size=integer l=identifierlist) {
+ : ^(OP_VARNODE s=space_symbol["varnode definition"] offset=integer size=integer
+ l=identifierlist) {
if (offset.bitLength() > 64) {
throw new SleighError("Unsupported offset: " + String.format("0x\%x", offset),
l.second.get(0));
@@ -503,11 +404,11 @@ varnodedef
identifierlist returns [Pair,VectorSTL> value]
@init {
- VectorSTL names = new VectorSTL();
- VectorSTL locations = new VectorSTL();
+ VectorSTL names = new VectorSTL<>();
+ VectorSTL locations = new VectorSTL<>();
}
@after {
- $value = new Pair,VectorSTL>(names, locations);
+ $value = new Pair<>(names, locations);
}
: ^(OP_IDENTIFIER_LIST (
^(OP_IDENTIFIER s=.) { names.push_back($s.getText()); locations.push_back(find(s)); }
@@ -516,7 +417,7 @@ identifierlist returns [Pair,VectorSTL> value]
stringoridentlist returns [VectorSTL value]
@init {
- $value = new VectorSTL();
+ $value = new VectorSTL<>();
}
: ^(OP_STRING_OR_IDENT_LIST (n=stringorident { $value.push_back(n); } )*)
;
@@ -531,7 +432,8 @@ bitrangedef
;
sbitrange
- : ^(OP_BITRANGE ^(OP_IDENTIFIER s=.) b=varnode_symbol["bitrange definition", true] i=integer j=integer) {
+ : ^(OP_BITRANGE ^(OP_IDENTIFIER s=.) b=varnode_symbol["bitrange definition", true] i=integer
+ j=integer) {
sc.defineBitrange(find(s), $s.getText(), b, toUInt($i.value), toUInt($j.value));
}
;
@@ -544,18 +446,22 @@ valueattach
@init {
sc.calcContextLayout();
}
- : ^(OP_VALUES a=valuelist["attach values"] b=intblist) { sc.attachValues(a.first, a.second, b); }
+ : ^(OP_VALUES a=valuelist["attach values"] b=intblist) {
+ sc.attachValues(a.first, a.second, b);
+ }
;
intblist returns [VectorSTL value]
@init {
- $value = new VectorSTL();
+ $value = new VectorSTL<>();
}
: ^(OP_INTBLIST (n=intbpart { $value.push_back(toLong(n)); } )*)
;
intbpart returns [RadixBigInteger value]
- : t=OP_WILDCARD { $value = new RadixBigInteger(find(t), "BADBEEF", 16); }
+ : t=OP_WILDCARD {
+ $value = RadixBigInteger.parse(input, OP_WILDCARD, find(t), "BADBEEF", 16);
+ }
| ^(OP_NEGATE i=integer) { $value = i.negate(); }
| i=integer { $value = i; }
;
@@ -564,7 +470,9 @@ nameattach
@init {
sc.calcContextLayout();
}
- : ^(OP_NAMES a=valuelist["attach variables"] b=stringoridentlist) { sc.attachNames(a.first, a.second, b); }
+ : ^(OP_NAMES a=valuelist["attach variables"] b=stringoridentlist) {
+ sc.attachNames(a.first, a.second, b);
+ }
;
varattach
@@ -578,11 +486,11 @@ varattach
valuelist[String purpose] returns [Pair,VectorSTL> value]
@init {
- VectorSTL symbols = new VectorSTL();
- VectorSTL locations = new VectorSTL();
+ VectorSTL symbols = new VectorSTL<>();
+ VectorSTL locations = new VectorSTL<>();
}
@after {
- $value = new Pair,VectorSTL>(symbols, locations);
+ $value = new Pair<>(symbols, locations);
}
: ^(OP_IDENTIFIER_LIST (n=value_symbol[purpose] {
symbols.push_back(n.first);
@@ -593,7 +501,7 @@ valuelist[String purpose] returns [Pair,VectorSTL value]
@init {
- $value = new VectorSTL();
+ $value = new VectorSTL<>();
}
: ^(OP_IDENTIFIER_LIST (n=varnode_symbol[purpose, false] {
$value.push_back(n);
@@ -624,13 +532,16 @@ macrodef
arguments returns [Pair,VectorSTL> value]
@init {
- VectorSTL names = new VectorSTL();
- VectorSTL locations = new VectorSTL();
+ VectorSTL names = new VectorSTL<>();
+ VectorSTL locations = new VectorSTL<>();
}
@after {
- $value = new Pair,VectorSTL>(names, locations);
+ $value = new Pair<>(names, locations);
}
- : ^(OP_ARGUMENTS (^(OP_IDENTIFIER s=.) { names.push_back(s.getText()); locations.push_back(find(s)); })+)
+ : ^(OP_ARGUMENTS (^(OP_IDENTIFIER s=.) {
+ names.push_back(s.getText());
+ locations.push_back(find(s));
+ })+)
| OP_EMPTY_LIST
;
@@ -660,7 +571,7 @@ bitpat_or_nil returns [PatternEquation value]
;
constructorlikelist
- : ^(OP_CTLIST ( definition | constructorlike )* )
+ : ^(OP_CTLIST ( definition | constructorlike )* )
;
constructor
@@ -670,7 +581,9 @@ constructor
;
ctorsemantic[Constructor ctor] returns [SectionVector value]
- : ^(t=OP_PCODE p=semantic[env, ctor.location, sc.pcode, $t, true, false]) { $value = p; }
+ : ^(t=OP_PCODE p=semantic[env, ctor.location, sc.pcode, $t, true, false]) {
+ $value = p;
+ }
| ^(OP_PCODE OP_UNIMPL) { /*unimpl unimplemented ; */ $value = null; }
;
@@ -717,7 +630,8 @@ printpiece[Constructor ct]
: ^(OP_IDENTIFIER t=.) {
if ($ctorstart::table && $ctorstart::firstTime) {
ct.addSyntax(t.getText());
- } else {
+ }
+ else {
sc.newOperand(find(t), ct, t.getText());
}
}
@@ -756,16 +670,27 @@ pequation returns [PatternEquation value]
SleighSymbol sym = sc.findSymbol(s.getText());
if (sym instanceof OperandSymbol) {
$value = sc.constrainOperand(find(t), (OperandSymbol) sym, e);
- } else {
+ }
+ else {
FamilySymbol fs = (FamilySymbol) sym;
$value = new EqualEquation(find(t), fs.getPatternValue(), e);
}
}
- | ^(t=OP_NOTEQUAL f=family_symbol["pattern equation"] e=pexpression2) { $value = new NotEqualEquation(find(t), f.getPatternValue(), e); }
- | ^(t=OP_LESS f=family_symbol["pattern equation"] e=pexpression2) { $value = new LessEquation(find(t), f.getPatternValue(), e); }
- | ^(t=OP_LESSEQUAL f=family_symbol["pattern equation"] e=pexpression2) { $value = new LessEqualEquation(find(t), f.getPatternValue(), e); }
- | ^(t=OP_GREAT f=family_symbol["pattern equation"] e=pexpression2) { $value = new GreaterEquation(find(t), f.getPatternValue(), e); }
- | ^(t=OP_GREATEQUAL f=family_symbol["pattern equation"] e=pexpression2) { $value = new GreaterEqualEquation(find(t), f.getPatternValue(), e); }
+ | ^(t=OP_NOTEQUAL f=family_symbol["pattern equation"] e=pexpression2) {
+ $value = new NotEqualEquation(find(t), f.getPatternValue(), e);
+ }
+ | ^(t=OP_LESS f=family_symbol["pattern equation"] e=pexpression2) {
+ $value = new LessEquation(find(t), f.getPatternValue(), e);
+ }
+ | ^(t=OP_LESSEQUAL f=family_symbol["pattern equation"] e=pexpression2) {
+ $value = new LessEqualEquation(find(t), f.getPatternValue(), e);
+ }
+ | ^(t=OP_GREAT f=family_symbol["pattern equation"] e=pexpression2) {
+ $value = new GreaterEquation(find(t), f.getPatternValue(), e);
+ }
+ | ^(t=OP_GREATEQUAL f=family_symbol["pattern equation"] e=pexpression2) {
+ $value = new GreaterEqualEquation(find(t), f.getPatternValue(), e);
+ }
| ps=pequation_symbol["pattern equation"] { $value = ps; }
| ^(OP_PARENTHESIZED l=pequation) { $value = l; }
@@ -777,14 +702,16 @@ family_or_operand_symbol[String purpose] returns [Tree value]
SleighSymbol sym = sc.findSymbol($s.getText());
if (sym == null) {
unknownSymbolError($s.getText(), find($s), "family or operand", purpose);
- } else if(sym.getType() != symbol_type.value_symbol
- && sym.getType() != symbol_type.valuemap_symbol
- && sym.getType() != symbol_type.context_symbol
- && sym.getType() != symbol_type.name_symbol
- && sym.getType() != symbol_type.varnodelist_symbol
- && sym.getType() != symbol_type.operand_symbol) {
+ }
+ else if (sym.getType() != symbol_type.value_symbol &&
+ sym.getType() != symbol_type.valuemap_symbol &&
+ sym.getType() != symbol_type.context_symbol &&
+ sym.getType() != symbol_type.name_symbol &&
+ sym.getType() != symbol_type.varnodelist_symbol &&
+ sym.getType() != symbol_type.operand_symbol) {
wrongSymbolTypeError(sym, find($s), "family or operand", purpose);
- } else {
+ }
+ else {
$value = $s;
}
}
@@ -798,25 +725,32 @@ pequation_symbol[String purpose] returns [PatternEquation value]
Location location = find(s);
SleighSymbol sym = sc.findSymbol($s.getText());
if (sym == null) {
- unknownSymbolError($s.getText(), find($s), "family, operand, epsilon, or subtable", purpose);
- } else if(sym.getType() == symbol_type.value_symbol
- || sym.getType() == symbol_type.valuemap_symbol
- || sym.getType() == symbol_type.context_symbol
- || sym.getType() == symbol_type.name_symbol
- || sym.getType() == symbol_type.varnodelist_symbol) {
+ unknownSymbolError($s.getText(), find($s), "family, operand, epsilon, or subtable",
+ purpose);
+ }
+ else if (sym.getType() == symbol_type.value_symbol ||
+ sym.getType() == symbol_type.valuemap_symbol ||
+ sym.getType() == symbol_type.context_symbol ||
+ sym.getType() == symbol_type.name_symbol ||
+ sym.getType() == symbol_type.varnodelist_symbol) {
$value = sc.defineInvisibleOperand(location, (FamilySymbol) sym);
- } else if(sym.getType() == symbol_type.operand_symbol) {
+ }
+ else if (sym.getType() == symbol_type.operand_symbol) {
OperandSymbol os = (OperandSymbol) sym;
$value = new OperandEquation(location, os.getIndex()); sc.selfDefine(os);
- } else if(sym.getType() == symbol_type.epsilon_symbol) {
+ }
+ else if (sym.getType() == symbol_type.epsilon_symbol) {
SpecificSymbol ss = (SpecificSymbol) sym;
$value = new UnconstrainedEquation(location, ss.getPatternExpression());
- } else if(sym.getType() == symbol_type.subtable_symbol) {
+ }
+ else if (sym.getType() == symbol_type.subtable_symbol) {
SubtableSymbol ss = (SubtableSymbol) sym;
$value = sc.defineInvisibleOperand(location, ss);
- } else {
+ }
+ else {
$value = null;
- wrongSymbolTypeError(sym, find($s), "family, operand, epsilon, or subtable", purpose);
+ wrongSymbolTypeError(sym, find($s), "family, operand, epsilon, or subtable",
+ purpose);
}
}
| t=OP_WILDCARD {
@@ -825,78 +759,148 @@ pequation_symbol[String purpose] returns [PatternEquation value]
;
pexpression returns [PatternExpression value]
- : ^(t=OP_OR l=pexpression r=pexpression) { $value = new OrExpression(find(t), l, r); }
- | ^(t=OP_XOR l=pexpression r=pexpression) { $value = new XorExpression(find(t), l, r); }
- | ^(t=OP_AND l=pexpression r=pexpression) { $value = new AndExpression(find(t), l, r); }
- | ^(t=OP_LEFT l=pexpression r=pexpression) { $value = new LeftShiftExpression(find(t), l, r); }
- | ^(t=OP_RIGHT l=pexpression r=pexpression) { $value = new RightShiftExpression(find(t), l, r); }
- | ^(t=OP_ADD l=pexpression r=pexpression) { $value = new PlusExpression(find(t), l, r); }
- | ^(t=OP_SUB l=pexpression r=pexpression) { $value = new SubExpression(find(t), l, r); }
- | ^(t=OP_MULT l=pexpression r=pexpression) { $value = new MultExpression(find(t), l, r); }
- | ^(t=OP_DIV l=pexpression r=pexpression) { $value = new DivExpression(find(t), l, r); }
+ : ^(t=OP_OR l=pexpression r=pexpression) {
+ $value = new OrExpression(find(t), l, r);
+ }
+ | ^(t=OP_XOR l=pexpression r=pexpression) {
+ $value = new XorExpression(find(t), l, r);
+ }
+ | ^(t=OP_AND l=pexpression r=pexpression) {
+ $value = new AndExpression(find(t), l, r);
+ }
+ | ^(t=OP_LEFT l=pexpression r=pexpression) {
+ $value = new LeftShiftExpression(find(t), l, r);
+ }
+ | ^(t=OP_RIGHT l=pexpression r=pexpression) {
+ $value = new RightShiftExpression(find(t), l, r);
+ }
+ | ^(t=OP_ADD l=pexpression r=pexpression) {
+ $value = new PlusExpression(find(t), l, r);
+ }
+ | ^(t=OP_SUB l=pexpression r=pexpression) {
+ $value = new SubExpression(find(t), l, r);
+ }
+ | ^(t=OP_MULT l=pexpression r=pexpression) {
+ $value = new MultExpression(find(t), l, r);
+ }
+ | ^(t=OP_DIV l=pexpression r=pexpression) {
+ $value = new DivExpression(find(t), l, r);
+ }
- | ^(t=OP_NEGATE l=pexpression) { $value = new MinusExpression(find(t), l); }
- | ^(t=OP_INVERT l=pexpression) { $value = new NotExpression(find(t), l); }
+ | ^(t=OP_NEGATE l=pexpression) {
+ $value = new MinusExpression(find(t), l);
+ }
+ | ^(t=OP_INVERT l=pexpression) {
+ $value = new NotExpression(find(t), l);
+ }
-// | ^(OP_APPLY n=identifier o=pexpression2_operands) { $value = $n.value + "(" + $o.value + ")"; } // for globalset!!!
- | y=pattern_symbol["pattern expression"] { $value = $y.expr; }
- | i=integer { $value = new ConstantValue(i.location, toLong(i)); }
- | ^(OP_PARENTHESIZED l=pexpression) { $value = l; }
+/* | ^(OP_APPLY n=identifier o=pexpression2_operands) { // for globalset!!!
+ $value = $n.value + "(" + $o.value + ")";
+ } */
+ | y=pattern_symbol["pattern expression"] {
+ $value = $y.expr;
+ }
+ | i=integer {
+ $value = new ConstantValue(i.location, toLong(i));
+ }
+ | ^(OP_PARENTHESIZED l=pexpression) {
+ $value = l;
+ }
;
pexpression2 returns [PatternExpression value]
- : ^(t=OP_OR l=pexpression2 r=pexpression2) { $value = new OrExpression(find(t), l, r); }
- | ^(t=OP_XOR l=pexpression2 r=pexpression2) { $value = new XorExpression(find(t), l, r); }
- | ^(t=OP_AND l=pexpression2 r=pexpression2) { $value = new AndExpression(find(t), l, r); }
- | ^(t=OP_LEFT l=pexpression2 r=pexpression2) { $value = new LeftShiftExpression(find(t), l, r); }
- | ^(t=OP_RIGHT l=pexpression2 r=pexpression2) { $value = new RightShiftExpression(find(t), l, r); }
- | ^(t=OP_ADD l=pexpression2 r=pexpression2) { $value = new PlusExpression(find(t), l, r); }
- | ^(t=OP_SUB l=pexpression2 r=pexpression2) { $value = new SubExpression(find(t), l, r); }
- | ^(t=OP_MULT l=pexpression2 r=pexpression2) { $value = new MultExpression(find(t), l, r); }
- | ^(t=OP_DIV l=pexpression2 r=pexpression2) { $value = new DivExpression(find(t), l, r); }
+ : ^(t=OP_OR l=pexpression2 r=pexpression2) {
+ $value = new OrExpression(find(t), l, r);
+ }
+ | ^(t=OP_XOR l=pexpression2 r=pexpression2) {
+ $value = new XorExpression(find(t), l, r);
+ }
+ | ^(t=OP_AND l=pexpression2 r=pexpression2) {
+ $value = new AndExpression(find(t), l, r);
+ }
+ | ^(t=OP_LEFT l=pexpression2 r=pexpression2) {
+ $value = new LeftShiftExpression(find(t), l, r);
+ }
+ | ^(t=OP_RIGHT l=pexpression2 r=pexpression2) {
+ $value = new RightShiftExpression(find(t), l, r);
+ }
+ | ^(t=OP_ADD l=pexpression2 r=pexpression2) {
+ $value = new PlusExpression(find(t), l, r);
+ }
+ | ^(t=OP_SUB l=pexpression2 r=pexpression2) {
+ $value = new SubExpression(find(t), l, r);
+ }
+ | ^(t=OP_MULT l=pexpression2 r=pexpression2) {
+ $value = new MultExpression(find(t), l, r);
+ }
+ | ^(t=OP_DIV l=pexpression2 r=pexpression2) {
+ $value = new DivExpression(find(t), l, r);
+ }
- | ^(t=OP_NEGATE l=pexpression2) { $value = new MinusExpression(find(t), l); }
- | ^(t=OP_INVERT l=pexpression2) { $value = new NotExpression(find(t), l); }
+ | ^(t=OP_NEGATE l=pexpression2) {
+ $value = new MinusExpression(find(t), l);
+ }
+ | ^(t=OP_INVERT l=pexpression2) {
+ $value = new NotExpression(find(t), l);
+ }
-// | ^(OP_APPLY n=identifier o=pexpression2_operands) { $value = $n.value + "(" + $o.value + ")"; } // for globalset!!!
- | y=pattern_symbol2["pattern expression"] { $value = $y.expr; }
- | i=integer { $value = new ConstantValue(i.location, toLong(i)); }
- | ^(OP_PARENTHESIZED l=pexpression2) { $value = l; }
+/* | ^(OP_APPLY n=identifier o=pexpression2_operands) { // for globalset!!!
+ $value = $n.value + "(" + $o.value + ")";
+ } */
+ | y=pattern_symbol2["pattern expression"] {
+ $value = $y.expr;
+ }
+ | i=integer {
+ $value = new ConstantValue(i.location, toLong(i));
+ }
+ | ^(OP_PARENTHESIZED l=pexpression2) {
+ $value = l;
+ }
;
pattern_symbol[String purpose] returns [PatternExpression expr]
: ^(OP_IDENTIFIER s=.) {
SleighSymbol sym = sc.findSymbol($s.getText());
if (sym == null) {
- unknownSymbolError($s.getText(), find($s), "start, end, next2, operand, epsilon, or varnode", purpose);
- } else if(sym.getType() == symbol_type.operand_symbol) {
- OperandSymbol os = (OperandSymbol) sym;
- if (os.getDefiningSymbol() != null && os.getDefiningSymbol().getType() == symbol_type.subtable_symbol) {
- reportError(find($s), "Subtable symbol '" + sym.getName() + "' is not allowed in context block");
- }
- $expr = os.getPatternExpression();
- } else if(sym.getType() == symbol_type.start_symbol
- || sym.getType() == symbol_type.end_symbol
- || sym.getType() == symbol_type.next2_symbol
- || sym.getType() == symbol_type.flowdest_symbol
- || sym.getType() == symbol_type.flowref_symbol
- || sym.getType() == symbol_type.epsilon_symbol
- || sym.getType() == symbol_type.varnode_symbol) {
+ unknownSymbolError($s.getText(), find($s),
+ "start, end, next2, operand, epsilon, or varnode", purpose);
+ }
+ else if (sym.getType() == symbol_type.operand_symbol) {
+ OperandSymbol os = (OperandSymbol) sym;
+ if (os.getDefiningSymbol() != null &&
+ os.getDefiningSymbol().getType() == symbol_type.subtable_symbol) {
+ reportError(find($s), "Subtable symbol '" + sym.getName() +
+ "' is not allowed in context block");
+ }
+ $expr = os.getPatternExpression();
+ }
+ else if (sym.getType() == symbol_type.start_symbol ||
+ sym.getType() == symbol_type.end_symbol ||
+ sym.getType() == symbol_type.next2_symbol ||
+ sym.getType() == symbol_type.flowdest_symbol ||
+ sym.getType() == symbol_type.flowref_symbol ||
+ sym.getType() == symbol_type.epsilon_symbol ||
+ sym.getType() == symbol_type.varnode_symbol) {
SpecificSymbol ss = (SpecificSymbol) sym;
$expr = ss.getPatternExpression();
- } else if(sym.getType() == symbol_type.value_symbol
- || sym.getType() == symbol_type.valuemap_symbol
- || sym.getType() == symbol_type.context_symbol
- || sym.getType() == symbol_type.name_symbol
- || sym.getType() == symbol_type.varnodelist_symbol) {
+ }
+ else if (sym.getType() == symbol_type.value_symbol ||
+ sym.getType() == symbol_type.valuemap_symbol ||
+ sym.getType() == symbol_type.context_symbol ||
+ sym.getType() == symbol_type.name_symbol ||
+ sym.getType() == symbol_type.varnodelist_symbol) {
if (sym.getType() == symbol_type.context_symbol) {
FamilySymbol z = (FamilySymbol) sym;
$expr = z.getPatternValue();
- } else {
- reportError(find($s), "Global symbol '" + sym.getName() + "' is not allowed in action expression");
}
- } else {
- wrongSymbolTypeError(sym, find($s), "start, end, next2, operand, epsilon, or varnode", purpose);
+ else {
+ reportError(find($s), "Global symbol '" + sym.getName() +
+ "' is not allowed in action expression");
+ }
+ }
+ else {
+ wrongSymbolTypeError(sym, find($s),
+ "start, end, next2, operand, epsilon, or varnode", purpose);
}
}
| t=OP_WILDCARD {
@@ -909,26 +913,31 @@ pattern_symbol2[String purpose] returns [PatternExpression expr]
: ^(OP_IDENTIFIER s=.) {
SleighSymbol sym = sc.findSymbol($s.getText());
if (sym == null) {
- unknownSymbolError($s.getText(), find($s), "start, end, next2, operand, epsilon, or varnode", purpose);
- } else if(sym.getType() == symbol_type.start_symbol
- || sym.getType() == symbol_type.end_symbol
- || sym.getType() == symbol_type.next2_symbol
- || sym.getType() == symbol_type.flowdest_symbol
- || sym.getType() == symbol_type.flowref_symbol
- || sym.getType() == symbol_type.operand_symbol
- || sym.getType() == symbol_type.epsilon_symbol
- || sym.getType() == symbol_type.varnode_symbol) {
+ unknownSymbolError($s.getText(), find($s),
+ "start, end, next2, operand, epsilon, or varnode", purpose);
+ }
+ else if (sym.getType() == symbol_type.start_symbol ||
+ sym.getType() == symbol_type.end_symbol ||
+ sym.getType() == symbol_type.next2_symbol ||
+ sym.getType() == symbol_type.flowdest_symbol ||
+ sym.getType() == symbol_type.flowref_symbol ||
+ sym.getType() == symbol_type.operand_symbol ||
+ sym.getType() == symbol_type.epsilon_symbol ||
+ sym.getType() == symbol_type.varnode_symbol) {
SpecificSymbol ss = (SpecificSymbol) sym;
$expr = ss.getPatternExpression();
- } else if(sym.getType() == symbol_type.value_symbol
- || sym.getType() == symbol_type.valuemap_symbol
- || sym.getType() == symbol_type.context_symbol
- || sym.getType() == symbol_type.name_symbol
- || sym.getType() == symbol_type.varnodelist_symbol) {
+ }
+ else if (sym.getType() == symbol_type.value_symbol ||
+ sym.getType() == symbol_type.valuemap_symbol ||
+ sym.getType() == symbol_type.context_symbol ||
+ sym.getType() == symbol_type.name_symbol ||
+ sym.getType() == symbol_type.varnodelist_symbol) {
FamilySymbol z = (FamilySymbol) sym;
$expr = z.getPatternValue();
- } else {
- wrongSymbolTypeError(sym, find($s), "start, end, next2, operand, epsilon, or varnode", purpose);
+ }
+ else {
+ wrongSymbolTypeError(sym, find($s),
+ "start, end, next2, operand, epsilon, or varnode", purpose);
}
}
| t=OP_WILDCARD {
@@ -944,7 +953,7 @@ contextblock returns [VectorSTL value]
cstatements returns[VectorSTL r]
@init {
- r = new VectorSTL();
+ r = new VectorSTL<>();
}
: cstatement[r]+
;
@@ -953,56 +962,70 @@ cstatement[VectorSTL r]
: ^(OP_ASSIGN ^(OP_IDENTIFIER id=.) e=pexpression) {
SleighSymbol sym = sc.findSymbol($id.getText());
if (sym == null) {
- unknownSymbolError($id.getText(), find($id), "context or operand", "context block lvalue");
- } else if(sym.getType() == symbol_type.context_symbol) {
+ unknownSymbolError($id.getText(), find($id), "context or operand",
+ "context block lvalue");
+ }
+ else if (sym.getType() == symbol_type.context_symbol) {
ContextSymbol t = (ContextSymbol) sym;
if (!sc.contextMod(r, t, e)) {
- reportError(find($id), "Cannot use 'inst_next' or 'inst_next2' to set context variable: '" + t.getName() + "'");
+ reportError(find($id),
+ "Cannot use 'inst_next' or 'inst_next2' to set context variable: '" +
+ t.getName() + "'");
}
- } else if(sym.getType() == symbol_type.operand_symbol) {
+ }
+ else if (sym.getType() == symbol_type.operand_symbol) {
OperandSymbol t = (OperandSymbol) sym;
sc.defineOperand(find(id), t, e);
- } else {
+ }
+ else {
wrongSymbolTypeError(sym, find(id), "context or operand", "context block lvalue");
}
}
| ^(OP_APPLY ^(OP_IDENTIFIER id=.) ^(OP_IDENTIFIER arg1=.) ^(OP_IDENTIFIER arg2=.)) {
if (!"globalset".equals(id.getText())) {
reportError(find($id), "unknown context block function '" + id.getText() + "'");
- } else {
+ }
+ else {
SleighSymbol sym = sc.findSymbol($arg2.getText());
if (sym == null) {
unknownSymbolError($arg2.getText(), find($arg2), "context", "globalset call");
- } else if(sym.getType() == symbol_type.context_symbol) {
+ }
+ else if (sym.getType() == symbol_type.context_symbol) {
ContextSymbol t = (ContextSymbol) sym;
sym = sc.findSymbol($arg1.getText());
if (sym == null) {
- unknownSymbolError($arg1.getText(), find($arg1), "family or specific", "globalset call");
- } else if(sym.getType() == symbol_type.value_symbol
- || sym.getType() == symbol_type.valuemap_symbol
- || sym.getType() == symbol_type.context_symbol
- || sym.getType() == symbol_type.name_symbol
- || sym.getType() == symbol_type.varnodelist_symbol
- || sym.getType() == symbol_type.start_symbol
- || sym.getType() == symbol_type.end_symbol
- || sym.getType() == symbol_type.next2_symbol
- || sym.getType() == symbol_type.flowdest_symbol
- || sym.getType() == symbol_type.flowref_symbol
- || sym.getType() == symbol_type.operand_symbol
- || sym.getType() == symbol_type.epsilon_symbol
- || sym.getType() == symbol_type.varnode_symbol) {
- sc.contextSet(r, (TripleSymbol) sym, t);
- } else {
- wrongSymbolTypeError(sym, find($arg1), "family or specific", "globalset call");
+ unknownSymbolError($arg1.getText(), find($arg1), "family or specific",
+ "globalset call");
}
- } else {
+ else if (sym.getType() == symbol_type.value_symbol ||
+ sym.getType() == symbol_type.valuemap_symbol ||
+ sym.getType() == symbol_type.context_symbol ||
+ sym.getType() == symbol_type.name_symbol ||
+ sym.getType() == symbol_type.varnodelist_symbol ||
+ sym.getType() == symbol_type.start_symbol ||
+ sym.getType() == symbol_type.end_symbol ||
+ sym.getType() == symbol_type.next2_symbol ||
+ sym.getType() == symbol_type.flowdest_symbol ||
+ sym.getType() == symbol_type.flowref_symbol ||
+ sym.getType() == symbol_type.operand_symbol ||
+ sym.getType() == symbol_type.epsilon_symbol ||
+ sym.getType() == symbol_type.varnode_symbol) {
+ sc.contextSet(r, (TripleSymbol) sym, t);
+ }
+ else {
+ wrongSymbolTypeError(sym, find($arg1), "family or specific",
+ "globalset call");
+ }
+ }
+ else {
wrongSymbolTypeError(sym, find(arg2), "context", "globalset call");
}
}
}
;
-semantic[ParsingEnvironment pe, Location containerLoc, PcodeCompile pcode, Tree where, boolean sectionsAllowed, boolean isMacroParse] returns [SectionVector rtl]
+semantic[ParsingEnvironment pe, Location containerLoc, PcodeCompile pcode, Tree where,
+ boolean sectionsAllowed, boolean isMacroParse] returns [SectionVector rtl]
scope {
SectionVector sections;
boolean containsMultipleSections;
@@ -1015,7 +1038,7 @@ semantic[ParsingEnvironment pe, Location containerLoc, PcodeCompile pcode, Tree
sc = null; // TODO: force failure with improper use of sc instead of pcode
this.env = pe;
this.pcode = pcode;
-
+
$semantic::sections = null;
$semantic::containsMultipleSections = false;
$semantic::nextStatementMustBeSectionLabel = false;
@@ -1035,10 +1058,12 @@ semantic[ParsingEnvironment pe, Location containerLoc, PcodeCompile pcode, Tree
}
if ($semantic::containsMultipleSections) {
$semantic::sections = pcode.finalNamedSection($semantic::sections, c);
- } else {
+ }
+ else {
if (!isMacroParse) {
$semantic::sections = pcode.standaloneSection(c);
- } else {
+ }
+ else {
$macrodef::macrobody = c;
}
}
@@ -1047,9 +1072,9 @@ semantic[ParsingEnvironment pe, Location containerLoc, PcodeCompile pcode, Tree
)
;
finally {
- this.sc = oldSC;
- this.env = oldEnv;
- this.pcode = null;
+ this.sc = oldSC;
+ this.env = oldEnv;
+ this.pcode = null;
}
code_block[Location startingPoint] returns [ConstructTpl rtl]
@@ -1059,7 +1084,8 @@ code_block[Location startingPoint] returns [ConstructTpl rtl]
scope Block;
@init {
$Block::ct = pcode.enterSection(startingPoint);
- $code_block::stmtLocation = new Location("", 0);
+ $code_block::stmtLocation = new Location("",
+ 0);
}
@after {
$rtl = $Block::ct;
@@ -1075,7 +1101,7 @@ statements
statement
scope Return;
@init {
- VectorSTL ops = new VectorSTL();
+ VectorSTL ops = new VectorSTL<>();
$Return::noReturn = false;
boolean wasSectionLabel = false;
boolean lookingForSectionLabel = $semantic::nextStatementMustBeSectionLabel;
@@ -1111,13 +1137,15 @@ statement
$semantic::nextStatementMustBeSectionLabel = true;
}
| s=section_label {
- if(!$semantic::canContainSections) {
+ if (!$semantic::canContainSections) {
reportError($code_block::stmtLocation, "No sections allowed");
}
wasSectionLabel = true;
if ($semantic::containsMultipleSections) {
- $semantic::sections = pcode.nextNamedSection($semantic::sections, $Block::ct, s.second);
- } else {
+ $semantic::sections = pcode.nextNamedSection($semantic::sections,
+ $Block::ct, s.second);
+ }
+ else {
$semantic::sections = pcode.firstNamedSection($Block::ct, s.second);
}
if ($Block::ct.getOpvec().empty() && $Block::ct.getResult() == null) {
@@ -1139,16 +1167,18 @@ declaration
label returns [Pair result]
: ^(OP_LABEL (^(OP_IDENTIFIER s=.) {
- SleighSymbol sym = pcode.findSymbol($s.getText());
+ SleighSymbol sym = pcode.findSymbol(find($s), $s.getText());
if (sym != null) {
- if(sym.getType() != symbol_type.label_symbol) {
+ if (sym.getType() != symbol_type.label_symbol) {
wrongSymbolTypeError(sym, find($s), "label", "label");
- } else {
- $result = new Pair(find(s), (LabelSymbol) sym);
}
- } else {
+ else {
+ $result = new Pair<>(find(s), (LabelSymbol) sym);
+ }
+ }
+ else {
Location where = find(s);
- $result = new Pair(where, pcode.defineLabel(where, $s.getText()));
+ $result = new Pair<>(where, pcode.defineLabel(where, $s.getText()));
}
}
| t=OP_WILDCARD {
@@ -1158,16 +1188,18 @@ label returns [Pair result]
section_label returns [Pair result]
: ^(OP_SECTION_LABEL (^(OP_IDENTIFIER s=.) {
- SleighSymbol sym = pcode.findSymbol($s.getText());
+ SleighSymbol sym = pcode.findSymbol(find($s), $s.getText());
if (sym != null) {
- if(sym.getType() != symbol_type.section_symbol) {
+ if (sym.getType() != symbol_type.section_symbol) {
wrongSymbolTypeError(sym, find($s), "section", "section");
- } else {
- $result = new Pair(find(s), (SectionSymbol) sym);
}
- } else {
+ else {
+ $result = new Pair<>(find(s), (SectionSymbol) sym);
+ }
+ }
+ else {
Location where = find(s);
- $result = new Pair(where, pcode.newSectionSymbol(where, $s.getText()));
+ $result = new Pair<>(where, pcode.newSectionSymbol(where, $s.getText()));
}
}
| t=OP_WILDCARD {
@@ -1178,12 +1210,14 @@ section_label returns [Pair result]
section_symbol[String purpose] returns [SectionSymbol value]
: ^(OP_IDENTIFIER s=.) {
Location location = find(s);
- SleighSymbol sym = pcode.findSymbol($s.getText());
+ SleighSymbol sym = pcode.findSymbol(find($s), $s.getText());
if (sym == null) {
$value = pcode.newSectionSymbol(location, $s.getText());
- } else if(sym.getType() != symbol_type.section_symbol) {
+ }
+ else if (sym.getType() != symbol_type.section_symbol) {
wrongSymbolTypeError(sym, find($s), "section", purpose);
- } else {
+ }
+ else {
$value = (SectionSymbol) sym;
}
}
@@ -1196,38 +1230,46 @@ assignment returns [VectorSTL value]
@after {
$code_block::stmtLocation = find(t);
}
- : ^(t=OP_ASSIGN ^(OP_BITRANGE ss=specific_symbol["bit range assignment"] a=integer b=integer) e=expr) {
- $value = pcode.assignBitRange(find(t), ss.getVarnode(), toUInt($a.value), toUInt($b.value), e);
+ : ^(t=OP_ASSIGN ^(OP_BITRANGE ss=specific_symbol["bit range assignment"] a=integer b=integer)
+ e=expr) {
+ $value = pcode.assignBitRange(find(t), ss.getVarnode(), toUInt($a.value),
+ toUInt($b.value), e);
}
- | ^(t=OP_ASSIGN ^(OP_DECLARATIVE_SIZE n=unbound_identifier["variable declaration/assignment"] i=integer) e=expr) {
+ | ^(t=OP_ASSIGN ^(OP_DECLARATIVE_SIZE n=unbound_identifier["variable declaration/assignment"]
+ i=integer) e=expr) {
$value = pcode.newOutput(find(n), true, e, n.getText(), toUInt($i.value));
}
- | ^(OP_LOCAL t=OP_ASSIGN ^(OP_DECLARATIVE_SIZE n=unbound_identifier["variable declaration/assignment"] i=integer) e=expr) {
+ | ^(OP_LOCAL t=OP_ASSIGN ^(OP_DECLARATIVE_SIZE
+ n=unbound_identifier["variable declaration/assignment"] i=integer) e=expr) {
$value = pcode.newOutput(find(n), true, e, n.getText(), toUInt($i.value));
}
| ^(OP_LOCAL t=OP_ASSIGN n=unbound_identifier["variable declaration/assignment"] e=expr) {
$value = pcode.newOutput(find(n), true, e, n.getText());
}
| ^(t=OP_ASSIGN ^(OP_IDENTIFIER id=.) e=expr) {
- SleighSymbol sym = pcode.findSymbol($id.getText());
+ SleighSymbol sym = pcode.findSymbol(find($id), $id.getText());
if (sym == null) {
$value = pcode.newOutput(find(id), false, e, $id.getText());
- } else if (sym instanceof BitrangeSymbol) {
- BitrangeSymbol bitSym = (BitrangeSymbol)sym;
- VarnodeSymbol parent = bitSym.getParentSymbol();
- $value = pcode.assignBitRange(find(t), parent.getVarnode(),
- bitSym.getBitOffset(),
- bitSym.numBits(),e);
- } else if(sym.getType() != symbol_type.start_symbol
- && sym.getType() != symbol_type.end_symbol
- && sym.getType() != symbol_type.next2_symbol
- && sym.getType() != symbol_type.flowdest_symbol
- && sym.getType() != symbol_type.flowref_symbol
- && sym.getType() != symbol_type.operand_symbol
- && sym.getType() != symbol_type.epsilon_symbol
- && sym.getType() != symbol_type.varnode_symbol) {
- wrongSymbolTypeError(sym, find(id), "start, end, next2, operand, epsilon, or varnode", "assignment");
- } else {
+ }
+ else if (sym instanceof BitrangeSymbol) {
+ BitrangeSymbol bitSym = (BitrangeSymbol)sym;
+ VarnodeSymbol parent = bitSym.getParentSymbol();
+ $value = pcode.assignBitRange(find(t), parent.getVarnode(),
+ bitSym.getBitOffset(),
+ bitSym.numBits(), e);
+ }
+ else if (sym.getType() != symbol_type.start_symbol &&
+ sym.getType() != symbol_type.end_symbol &&
+ sym.getType() != symbol_type.next2_symbol &&
+ sym.getType() != symbol_type.flowdest_symbol &&
+ sym.getType() != symbol_type.flowref_symbol &&
+ sym.getType() != symbol_type.operand_symbol &&
+ sym.getType() != symbol_type.epsilon_symbol &&
+ sym.getType() != symbol_type.varnode_symbol) {
+ wrongSymbolTypeError(sym, find(id),
+ "start, end, next2, operand, epsilon, or varnode", "assignment");
+ }
+ else {
VarnodeTpl v = ((SpecificSymbol) sym).getVarnode();
e.setOutput(find(t), v);
$value = ExprTree.toVector(e);
@@ -1242,7 +1284,9 @@ assignment returns [VectorSTL value]
;
bitrange returns [ExprTree value]
- : ^(t=OP_BITRANGE ss=specific_symbol["bit range"] a=integer b=integer) { $value = pcode.createBitRange(find(t), ss, toUInt($a.value), toUInt($b.value)); }
+ : ^(t=OP_BITRANGE ss=specific_symbol["bit range"] a=integer b=integer) {
+ $value = pcode.createBitRange(find(t), ss, toUInt($a.value), toUInt($b.value));
+ }
;
sizedstar returns [Pair value]
@@ -1250,7 +1294,7 @@ sizedstar returns [Pair value]
StarQuality q = null;
}
@after {
- $value = new Pair(q, e);
+ $value = new Pair<>(q, e);
}
: ^(t=OP_DEREFERENCE s=space_symbol["sized star operator"] i=integer e=expr) {
q = new StarQuality(find(t));
@@ -1279,14 +1323,16 @@ sizedstarv returns [Pair value]
StarQuality q = null;
}
@after {
- $value = new Pair(q, ss.getVarnode());
+ $value = new Pair<>(q, ss.getVarnode());
}
- : ^(t=OP_DEREFERENCE s=space_symbol["sized star operator"] i=integer ss=specific_symbol["varnode reference"]) {
+ : ^(t=OP_DEREFERENCE s=space_symbol["sized star operator"] i=integer
+ ss=specific_symbol["varnode reference"]) {
q = new StarQuality(find(t));
q.setSize(toUInt($i.value));
q.setId(new ConstTpl(s.getSpace()));
}
- | ^(t=OP_DEREFERENCE s=space_symbol["sized star operator"] ss=specific_symbol["varnode reference"]) {
+ | ^(t=OP_DEREFERENCE s=space_symbol["sized star operator"]
+ ss=specific_symbol["varnode reference"]) {
q = new StarQuality(find(t));
q.setSize(0);
q.setId(new ConstTpl(s.getSpace()));
@@ -1308,14 +1354,15 @@ funcall returns [VectorSTL value]
$Return::noReturn = true;
}
: e=expr_apply {
- if (e instanceof VectorSTL>)
+ if (e instanceof VectorSTL>) {
$value = (VectorSTL) e;
+ }
else {
Location loc = null;
- if (e instanceof ExprTree) {
- loc = ((ExprTree)e).location;
+ if (e instanceof ExprTree et) {
+ loc = et.location;
}
- reportError(loc,"Functional operator requires a return value");
+ reportError(loc, "Functional operator requires a return value");
}
}
;
@@ -1347,29 +1394,34 @@ goto_stmt returns [VectorSTL ops]
$code_block::stmtLocation = find(t);
}
: ^(t=OP_GOTO j=jumpdest["goto destination"]) {
- $ops = pcode.createOpNoOut(find(t), $Jump::indirect ? OpCode.CPUI_BRANCHIND : OpCode.CPUI_BRANCH, j);
+ $ops = pcode.createOpNoOut(find(t), $Jump::indirect
+ ? OpCode.CPUI_BRANCHIND
+ : OpCode.CPUI_BRANCH, j);
}
;
jump_symbol[String purpose] returns [VarnodeTpl value]
: ^(OP_IDENTIFIER s=.) {
- SleighSymbol sym = pcode.findSymbol($s.getText());
+ SleighSymbol sym = pcode.findSymbol(find($s), $s.getText());
if (sym == null) {
unknownSymbolError($s.getText(), find($s), "start, end, or operand", purpose);
- } else if (sym.getType() == symbol_type.start_symbol ||
+ }
+ else if (sym.getType() == symbol_type.start_symbol ||
sym.getType() == symbol_type.end_symbol ||
sym.getType() == symbol_type.next2_symbol ||
sym.getType() == symbol_type.flowdest_symbol ||
sym.getType() == symbol_type.flowref_symbol) {
SpecificSymbol ss = (SpecificSymbol) sym;
$value = new VarnodeTpl(find($s), new ConstTpl(ConstTpl.const_type.j_curspace),
- ss.getVarnode().getOffset(),
- new ConstTpl(ConstTpl.const_type.j_curspace_size));
- } else if(sym.getType() == symbol_type.operand_symbol) {
+ ss.getVarnode().getOffset(),
+ new ConstTpl(ConstTpl.const_type.j_curspace_size));
+ }
+ else if (sym.getType() == symbol_type.operand_symbol) {
OperandSymbol os = (OperandSymbol) sym;
$value = os.getVarnode();
os.setCodeAddress();
- } else {
+ }
+ else {
wrongSymbolTypeError(sym, find($s), "start, end, or operand", purpose);
}
}
@@ -1385,27 +1437,30 @@ jumpdest[String purpose] returns [ExprTree value]
}
| ^(t=OP_JUMPDEST_DYNAMIC e=expr) {
$value = e;
- if(Jump_stack.isEmpty()) {
+ if (Jump_stack.isEmpty()) {
invalidDynamicTargetError(find(t), purpose);
- } else {
+ }
+ else {
$Jump::indirect = true;
}
}
| ^(t=OP_JUMPDEST_ABSOLUTE i=integer) {
- value = new ExprTree(find(t), new VarnodeTpl(find(t), new ConstTpl(ConstTpl.const_type.j_curspace),
- new ConstTpl(ConstTpl.const_type.real, toULong($i.value)),
- new ConstTpl(ConstTpl.const_type.j_curspace_size)));
+ value = new ExprTree(find(t), new VarnodeTpl(find(t),
+ new ConstTpl(ConstTpl.const_type.j_curspace),
+ new ConstTpl(ConstTpl.const_type.real, toULong($i.value)),
+ new ConstTpl(ConstTpl.const_type.j_curspace_size)));
}
| ^(t=OP_JUMPDEST_RELATIVE i=integer s=space_symbol[purpose]) {
AddrSpace spc = s.getSpace();
value = new ExprTree(find(t), new VarnodeTpl(find(t), new ConstTpl(spc),
- new ConstTpl(ConstTpl.const_type.real, toSLong($i.value)),
- new ConstTpl(ConstTpl.const_type.real, spc.getAddrSize())));
+ new ConstTpl(ConstTpl.const_type.real, toSLong($i.value)),
+ new ConstTpl(ConstTpl.const_type.real, spc.getAddrSize())));
}
| ^(t=OP_JUMPDEST_LABEL l=label) {
- value = new ExprTree(find(t), new VarnodeTpl(find(t), new ConstTpl(pcode.getConstantSpace()),
- new ConstTpl(ConstTpl.const_type.j_relative, l.second.getIndex()),
- new ConstTpl(ConstTpl.const_type.real, 4)));
+ value = new ExprTree(find(t), new VarnodeTpl(find(t),
+ new ConstTpl(pcode.getConstantSpace()),
+ new ConstTpl(ConstTpl.const_type.j_relative, l.second.getIndex()),
+ new ConstTpl(ConstTpl.const_type.real, 4)));
l.second.incrementRefCount();
}
;
@@ -1428,7 +1483,9 @@ call_stmt returns [VectorSTL ops]
$code_block::stmtLocation = find(t);
}
: ^(t=OP_CALL j=jumpdest["call destination"]) {
- $ops = pcode.createOpNoOut(find(t), $Jump::indirect ? OpCode.CPUI_CALLIND : OpCode.CPUI_CALL, j);
+ $ops = pcode.createOpNoOut(find(t), $Jump::indirect
+ ? OpCode.CPUI_CALLIND
+ : OpCode.CPUI_CALL, j);
}
;
@@ -1453,63 +1510,155 @@ export[ConstructTpl rtl] returns [ConstructTpl value]
;
expr returns [ExprTree value]
- : ^(t=OP_BOOL_OR l=expr r=expr) { $value = pcode.createOp(find(t), OpCode.CPUI_BOOL_OR,l,r); }
- | ^(t=OP_BOOL_XOR l=expr r=expr) { $value = pcode.createOp(find(t), OpCode.CPUI_BOOL_XOR,l,r); }
- | ^(t=OP_BOOL_AND l=expr r=expr) { $value = pcode.createOp(find(t), OpCode.CPUI_BOOL_AND,l,r); }
-
- | ^(t=OP_OR l=expr r=expr) { $value = pcode.createOp(find(t), OpCode.CPUI_INT_OR,l,r); }
- | ^(t=OP_XOR l=expr r=expr) { $value = pcode.createOp(find(t), OpCode.CPUI_INT_XOR,l,r); }
- | ^(t=OP_AND l=expr r=expr) { $value = pcode.createOp(find(t), OpCode.CPUI_INT_AND,l,r); }
-
- | ^(t=OP_EQUAL l=expr r=expr) { $value = pcode.createOp(find(t), OpCode.CPUI_INT_EQUAL,l,r); }
- | ^(t=OP_NOTEQUAL l=expr r=expr) { $value = pcode.createOp(find(t), OpCode.CPUI_INT_NOTEQUAL,l,r); }
- | ^(t=OP_FEQUAL l=expr r=expr) { $value = pcode.createOp(find(t), OpCode.CPUI_FLOAT_EQUAL,l,r); }
- | ^(t=OP_FNOTEQUAL l=expr r=expr) { $value = pcode.createOp(find(t), OpCode.CPUI_FLOAT_NOTEQUAL,l,r); }
-
- | ^(t=OP_LESS l=expr r=expr) { $value = pcode.createOp(find(t), OpCode.CPUI_INT_LESS,l,r); }
- | ^(t=OP_GREATEQUAL l=expr r=expr) { $value = pcode.createOp(find(t), OpCode.CPUI_INT_LESSEQUAL,r,l); }
- | ^(t=OP_LESSEQUAL l=expr r=expr) { $value = pcode.createOp(find(t), OpCode.CPUI_INT_LESSEQUAL,l,r); }
- | ^(t=OP_GREAT l=expr r=expr) { $value = pcode.createOp(find(t), OpCode.CPUI_INT_LESS,r,l); }
- | ^(t=OP_SLESS l=expr r=expr) { $value = pcode.createOp(find(t), OpCode.CPUI_INT_SLESS,l,r); }
- | ^(t=OP_SGREATEQUAL l=expr r=expr) { $value = pcode.createOp(find(t), OpCode.CPUI_INT_SLESSEQUAL,r,l); }
- | ^(t=OP_SLESSEQUAL l=expr r=expr) { $value = pcode.createOp(find(t), OpCode.CPUI_INT_SLESSEQUAL,l,r); }
- | ^(t=OP_SGREAT l=expr r=expr) { $value = pcode.createOp(find(t), OpCode.CPUI_INT_SLESS,r,l); }
- | ^(t=OP_FLESS l=expr r=expr) { $value = pcode.createOp(find(t), OpCode.CPUI_FLOAT_LESS,l,r); }
- | ^(t=OP_FGREATEQUAL l=expr r=expr) { $value = pcode.createOp(find(t), OpCode.CPUI_FLOAT_LESSEQUAL,r,l); }
- | ^(t=OP_FLESSEQUAL l=expr r=expr) { $value = pcode.createOp(find(t), OpCode.CPUI_FLOAT_LESSEQUAL,l,r); }
- | ^(t=OP_FGREAT l=expr r=expr) { $value = pcode.createOp(find(t), OpCode.CPUI_FLOAT_LESS,r,l); }
-
- | ^(t=OP_LEFT l=expr r=expr) { $value = pcode.createOp(find(t), OpCode.CPUI_INT_LEFT,l,r); }
- | ^(t=OP_RIGHT l=expr r=expr) { $value = pcode.createOp(find(t), OpCode.CPUI_INT_RIGHT,l,r); }
- | ^(t=OP_SRIGHT l=expr r=expr) { $value = pcode.createOp(find(t), OpCode.CPUI_INT_SRIGHT,l,r); }
-
- | ^(t=OP_ADD l=expr r=expr) { $value = pcode.createOp(find(t), OpCode.CPUI_INT_ADD,l,r); }
- | ^(t=OP_SUB l=expr r=expr) { $value = pcode.createOp(find(t), OpCode.CPUI_INT_SUB,l,r); }
- | ^(t=OP_FADD l=expr r=expr) { $value = pcode.createOp(find(t), OpCode.CPUI_FLOAT_ADD,l,r); }
- | ^(t=OP_FSUB l=expr r=expr) { $value = pcode.createOp(find(t), OpCode.CPUI_FLOAT_SUB,l,r); }
-
- | ^(t=OP_MULT l=expr r=expr) { $value = pcode.createOp(find(t), OpCode.CPUI_INT_MULT,l,r); }
- | ^(t=OP_DIV l=expr r=expr) { $value = pcode.createOp(find(t), OpCode.CPUI_INT_DIV,l,r); }
- | ^(t=OP_REM l=expr r=expr) { $value = pcode.createOp(find(t), OpCode.CPUI_INT_REM,l,r); }
- | ^(t=OP_SDIV l=expr r=expr) { $value = pcode.createOp(find(t), OpCode.CPUI_INT_SDIV,l,r); }
- | ^(t=OP_SREM l=expr r=expr) { $value = pcode.createOp(find(t), OpCode.CPUI_INT_SREM,l,r); }
- | ^(t=OP_FMULT l=expr r=expr) { $value = pcode.createOp(find(t), OpCode.CPUI_FLOAT_MULT,l,r); }
- | ^(t=OP_FDIV l=expr r=expr) { $value = pcode.createOp(find(t), OpCode.CPUI_FLOAT_DIV,l,r); }
-
- | ^(t=OP_NOT l=expr) { $value = pcode.createOp(find(t), OpCode.CPUI_BOOL_NEGATE,l); }
- | ^(t=OP_INVERT l=expr) { $value = pcode.createOp(find(t), OpCode.CPUI_INT_NEGATE,l); }
- | ^(t=OP_NEGATE l=expr) { $value = pcode.createOp(find(t), OpCode.CPUI_INT_2COMP,l); }
- | ^(t=OP_FNEGATE l=expr) { $value = pcode.createOp(find(t), OpCode.CPUI_FLOAT_NEG,l); }
- | s=sizedstar { $value = pcode.createLoad(s.first.location, s.first, s.second); }
-
- | a=expr_apply { $value = (ExprTree) $a.value; }
- | v=varnode_or_bitsym["expression"] { $value = $v.value; }
- | b=bitrange { $value = $b.value; }
- | i=integer { $value = new ExprTree(i.location, new VarnodeTpl(i.location, new ConstTpl(pcode.getConstantSpace()),
- new ConstTpl(ConstTpl.const_type.real, toLong($i.value)),
- new ConstTpl(ConstTpl.const_type.real, 0)));
+ : ^(t=OP_BOOL_OR l=expr r=expr) {
+ $value = pcode.createOp(find(t), OpCode.CPUI_BOOL_OR,l,r);
+ }
+ | ^(t=OP_BOOL_XOR l=expr r=expr) {
+ $value = pcode.createOp(find(t), OpCode.CPUI_BOOL_XOR,l,r);
+ }
+ | ^(t=OP_BOOL_AND l=expr r=expr) {
+ $value = pcode.createOp(find(t), OpCode.CPUI_BOOL_AND,l,r);
+ }
+
+ | ^(t=OP_OR l=expr r=expr) {
+ $value = pcode.createOp(find(t), OpCode.CPUI_INT_OR,l,r);
+ }
+ | ^(t=OP_XOR l=expr r=expr) {
+ $value = pcode.createOp(find(t), OpCode.CPUI_INT_XOR,l,r);
+ }
+ | ^(t=OP_AND l=expr r=expr) {
+ $value = pcode.createOp(find(t), OpCode.CPUI_INT_AND,l,r);
+ }
+
+ | ^(t=OP_EQUAL l=expr r=expr) {
+ $value = pcode.createOp(find(t), OpCode.CPUI_INT_EQUAL,l,r);
+ }
+ | ^(t=OP_NOTEQUAL l=expr r=expr) {
+ $value = pcode.createOp(find(t), OpCode.CPUI_INT_NOTEQUAL,l,r);
+ }
+ | ^(t=OP_FEQUAL l=expr r=expr) {
+ $value = pcode.createOp(find(t), OpCode.CPUI_FLOAT_EQUAL,l,r);
+ }
+ | ^(t=OP_FNOTEQUAL l=expr r=expr) {
+ $value = pcode.createOp(find(t), OpCode.CPUI_FLOAT_NOTEQUAL,l,r);
+ }
+
+ | ^(t=OP_LESS l=expr r=expr) {
+ $value = pcode.createOp(find(t), OpCode.CPUI_INT_LESS,l,r);
+ }
+ | ^(t=OP_GREATEQUAL l=expr r=expr) {
+ $value = pcode.createOp(find(t), OpCode.CPUI_INT_LESSEQUAL,r,l);
+ }
+ | ^(t=OP_LESSEQUAL l=expr r=expr) {
+ $value = pcode.createOp(find(t), OpCode.CPUI_INT_LESSEQUAL,l,r);
+ }
+ | ^(t=OP_GREAT l=expr r=expr) {
+ $value = pcode.createOp(find(t), OpCode.CPUI_INT_LESS,r,l);
+ }
+ | ^(t=OP_SLESS l=expr r=expr) {
+ $value = pcode.createOp(find(t), OpCode.CPUI_INT_SLESS,l,r);
+ }
+ | ^(t=OP_SGREATEQUAL l=expr r=expr) {
+ $value = pcode.createOp(find(t), OpCode.CPUI_INT_SLESSEQUAL,r,l);
+ }
+ | ^(t=OP_SLESSEQUAL l=expr r=expr) {
+ $value = pcode.createOp(find(t), OpCode.CPUI_INT_SLESSEQUAL,l,r);
+ }
+ | ^(t=OP_SGREAT l=expr r=expr) {
+ $value = pcode.createOp(find(t), OpCode.CPUI_INT_SLESS,r,l);
+ }
+ | ^(t=OP_FLESS l=expr r=expr) {
+ $value = pcode.createOp(find(t), OpCode.CPUI_FLOAT_LESS,l,r);
+ }
+ | ^(t=OP_FGREATEQUAL l=expr r=expr) {
+ $value = pcode.createOp(find(t), OpCode.CPUI_FLOAT_LESSEQUAL,r,l);
+ }
+ | ^(t=OP_FLESSEQUAL l=expr r=expr) {
+ $value = pcode.createOp(find(t), OpCode.CPUI_FLOAT_LESSEQUAL,l,r);
+ }
+ | ^(t=OP_FGREAT l=expr r=expr) {
+ $value = pcode.createOp(find(t), OpCode.CPUI_FLOAT_LESS,r,l);
+ }
+
+ | ^(t=OP_LEFT l=expr r=expr) {
+ $value = pcode.createOp(find(t), OpCode.CPUI_INT_LEFT,l,r);
+ }
+ | ^(t=OP_RIGHT l=expr r=expr) {
+ $value = pcode.createOp(find(t), OpCode.CPUI_INT_RIGHT,l,r);
+ }
+ | ^(t=OP_SRIGHT l=expr r=expr) {
+ $value = pcode.createOp(find(t), OpCode.CPUI_INT_SRIGHT,l,r);
+ }
+
+ | ^(t=OP_ADD l=expr r=expr) {
+ $value = pcode.createOp(find(t), OpCode.CPUI_INT_ADD,l,r);
+ }
+ | ^(t=OP_SUB l=expr r=expr) {
+ $value = pcode.createOp(find(t), OpCode.CPUI_INT_SUB,l,r);
+ }
+ | ^(t=OP_FADD l=expr r=expr) {
+ $value = pcode.createOp(find(t), OpCode.CPUI_FLOAT_ADD,l,r);
+ }
+ | ^(t=OP_FSUB l=expr r=expr) {
+ $value = pcode.createOp(find(t), OpCode.CPUI_FLOAT_SUB,l,r);
+ }
+
+ | ^(t=OP_MULT l=expr r=expr) {
+ $value = pcode.createOp(find(t), OpCode.CPUI_INT_MULT,l,r);
+ }
+ | ^(t=OP_DIV l=expr r=expr) {
+ $value = pcode.createOp(find(t), OpCode.CPUI_INT_DIV,l,r);
+ }
+ | ^(t=OP_REM l=expr r=expr) {
+ $value = pcode.createOp(find(t), OpCode.CPUI_INT_REM,l,r);
+ }
+ | ^(t=OP_SDIV l=expr r=expr) {
+ $value = pcode.createOp(find(t), OpCode.CPUI_INT_SDIV,l,r);
+ }
+ | ^(t=OP_SREM l=expr r=expr) {
+ $value = pcode.createOp(find(t), OpCode.CPUI_INT_SREM,l,r);
+ }
+ | ^(t=OP_FMULT l=expr r=expr) {
+ $value = pcode.createOp(find(t), OpCode.CPUI_FLOAT_MULT,l,r);
+ }
+ | ^(t=OP_FDIV l=expr r=expr) {
+ $value = pcode.createOp(find(t), OpCode.CPUI_FLOAT_DIV,l,r);
+ }
+
+ | ^(t=OP_NOT l=expr) {
+ $value = pcode.createOp(find(t), OpCode.CPUI_BOOL_NEGATE,l);
+ }
+ | ^(t=OP_INVERT l=expr) {
+ $value = pcode.createOp(find(t), OpCode.CPUI_INT_NEGATE,l);
+ }
+ | ^(t=OP_NEGATE l=expr) {
+ $value = pcode.createOp(find(t), OpCode.CPUI_INT_2COMP,l);
+ }
+ | ^(t=OP_FNEGATE l=expr) {
+ $value = pcode.createOp(find(t), OpCode.CPUI_FLOAT_NEG,l);
+ }
+ | s=sizedstar {
+ $value = pcode.createLoad(s.first.location, s.first, s.second);
+ }
+
+ | a=expr_apply {
+ $value = (ExprTree) $a.value;
+ }
+ | v=varnode_or_bitsym["expression"] {
+ $value = $v.value;
+ }
+ | b=bitrange {
+ $value = $b.value;
+ }
+ | i=int_lit {
+ $value = new ExprTree(i.location, new VarnodeTpl(i.location,
+ new ConstTpl(pcode.getConstantSpace()),
+ new ConstTpl(ConstTpl.const_type.real, toLong($i.value)),
+ new ConstTpl(ConstTpl.const_type.real, pcode.getDefaultConstantSize())));
+ }
+ | ^(OP_PARENTHESIZED l=expr) {
+ $value = l;
}
- | ^(OP_PARENTHESIZED l=expr) { $value = l; }
| ^(t=OP_BITRANGE2 ss=specific_symbol["expression"] i=integer) {
$value = pcode.createBitRange(find(t), ss, 0, toUInt($i.value) * 8);
@@ -1518,21 +1667,23 @@ expr returns [ExprTree value]
varnode_or_bitsym[String purpose] returns [ExprTree value]
: ^(t=OP_IDENTIFIER s=.) {
- SleighSymbol sym = pcode.findSymbol($s.getText());
- if (sym == null) {
- unknownSymbolError($s.getText(), find($s), "varnode or bitrange symbol", purpose);
- } else if (sym instanceof BitrangeSymbol) {
- BitrangeSymbol bitSym = (BitrangeSymbol)sym;
- $value = pcode.createBitRange(find(t), bitSym.getParentSymbol(),
- bitSym.getBitOffset(),
- bitSym.numBits());
- } else if (sym instanceof SpecificSymbol) {
- VarnodeTpl vTemp = ((SpecificSymbol)sym).getVarnode();
- $value = new ExprTree(vTemp.location, vTemp);
- } else {
- undeclaredSymbolError(sym, find($s), purpose);
- }
- }
+ SleighSymbol sym = pcode.findSymbol(find($s), $s.getText());
+ if (sym == null) {
+ unknownSymbolError($s.getText(), find($s), "varnode or bitrange symbol", purpose);
+ }
+ else if (sym instanceof BitrangeSymbol) {
+ BitrangeSymbol bitSym = (BitrangeSymbol)sym;
+ $value = pcode.createBitRange(find(t), bitSym.getParentSymbol(),
+ bitSym.getBitOffset(), bitSym.numBits());
+ }
+ else if (sym instanceof SpecificSymbol) {
+ VarnodeTpl vTemp = ((SpecificSymbol)sym).getVarnode();
+ $value = new ExprTree(vTemp.location, vTemp);
+ }
+ else {
+ undeclaredSymbolError(sym, find($s), purpose);
+ }
+ }
| v=varnode_adorned { $value = new ExprTree($v.value.location,$v.value); }
| t=OP_WILDCARD {
wildcardError($t, purpose);
@@ -1547,38 +1698,50 @@ expr_apply returns [Object value]
: ^(x=OP_APPLY ^(t=OP_IDENTIFIER s=.) o=expr_operands) {
Object internalFunction = pcode.findInternalFunction(find($s), $s.getText(), o);
if (internalFunction == null) {
- SleighSymbol sym = pcode.findSymbol($s.getText());
+ SleighSymbol sym = pcode.findSymbol(find($s), $s.getText());
if (sym == null) {
- unknownSymbolError($s.getText(), find($s), "macro, userop, or specific symbol", "macro, user operation, or subpiece application");
- } else if(sym.getType() == symbol_type.userop_symbol) {
- if($Return::noReturn) {
+ unknownSymbolError($s.getText(), find($s), "macro, userop, or specific symbol",
+ "macro, user operation, or subpiece application");
+ }
+ else if (sym.getType() == symbol_type.userop_symbol) {
+ if ($Return::noReturn) {
$value = pcode.createUserOpNoOut(find(s), (UserOpSymbol) sym, o);
- } else {
+ }
+ else {
$value = pcode.createUserOp((UserOpSymbol) sym, o);
}
- } else if(sym.getType() == symbol_type.macro_symbol) {
- if($Return::noReturn) {
+ }
+ else if (sym.getType() == symbol_type.macro_symbol) {
+ if ($Return::noReturn) {
$value = pcode.createMacroUse(find(x), (MacroSymbol) sym, o);
- } else {
+ }
+ else {
pcode.reportError(find($t), "macro invocation not allowed as expression");
}
- } else if(sym.getType() == symbol_type.start_symbol
- || sym.getType() == symbol_type.end_symbol
- || sym.getType() == symbol_type.next2_symbol
- || sym.getType() == symbol_type.flowdest_symbol
- || sym.getType() == symbol_type.flowref_symbol
- || sym.getType() == symbol_type.operand_symbol
- || sym.getType() == symbol_type.epsilon_symbol
- || sym.getType() == symbol_type.varnode_symbol) {
+ }
+ else if (sym.getType() == symbol_type.start_symbol ||
+ sym.getType() == symbol_type.end_symbol ||
+ sym.getType() == symbol_type.next2_symbol ||
+ sym.getType() == symbol_type.flowdest_symbol ||
+ sym.getType() == symbol_type.flowref_symbol ||
+ sym.getType() == symbol_type.operand_symbol ||
+ sym.getType() == symbol_type.epsilon_symbol ||
+ sym.getType() == symbol_type.varnode_symbol) {
if (o.size() != 1) {
pcode.reportError(find($t), "subpiece operation requires a single operand");
- } else {
- $value = pcode.createOp(find($s), OpCode.CPUI_SUBPIECE,new ExprTree(find($s), ((SpecificSymbol)sym).getVarnode()), o.get(0));
}
- } else {
- wrongSymbolTypeError(sym, find($s), "macro, userop, or specific symbol", "macro, user operation, or subpiece application");
+ else {
+ $value = pcode.createOp(find($s), OpCode.CPUI_SUBPIECE,
+ new ExprTree(find($s), ((SpecificSymbol) sym).getVarnode()),
+ o.get(0));
+ }
}
- } else {
+ else {
+ wrongSymbolTypeError(sym, find($s), "macro, userop, or specific symbol",
+ "macro, user operation, or subpiece application");
+ }
+ }
+ else {
$value = internalFunction;
}
}
@@ -1590,14 +1753,14 @@ expr_apply returns [Object value]
expr_operands returns [VectorSTL value]
scope Return;
@init {
- $value = new VectorSTL();
+ $value = new VectorSTL<>();
$Return::noReturn = false;
}
: (e=expr { value.push_back(e); })*
;
varnode_adorned returns [VarnodeTpl value]
- : ^(t=OP_TRUNCATION_SIZE n=integer m=integer) {
+ : ^(t=OP_TRUNCATION_SIZE n=int_lit m=integer) {
if (toULong($m.value) > 8) {
reportError(find(t), "Constant varnode size must not exceed 8 (" +
$n.value + ":" + $m.value + ")");
@@ -1606,8 +1769,12 @@ varnode_adorned returns [VarnodeTpl value]
new ConstTpl(ConstTpl.const_type.real, toLong($n.value)),
new ConstTpl(ConstTpl.const_type.real, toULong($m.value)));
}
- | ^(OP_ADDRESS_OF ^(OP_SIZING_SIZE i=integer) v=varnode) { $value = pcode.addressOf(v, toUInt($i.value)); }
- | ^(OP_ADDRESS_OF v=varnode) { $value = pcode.addressOf(v, 0); }
+ | ^(OP_ADDRESS_OF ^(OP_SIZING_SIZE i=integer) v=varnode) {
+ $value = pcode.addressOf(v, toUInt($i.value));
+ }
+ | ^(OP_ADDRESS_OF v=varnode) {
+ $value = pcode.addressOf(v, 0);
+ }
;
varnode returns [VarnodeTpl value]
@@ -1624,8 +1791,43 @@ identifier returns [String value, Tree tree]
| t=OP_WILDCARD { $value = null; $tree = s; }
;
-integer returns [RadixBigInteger value]
- : ^(OP_HEX_CONSTANT s=.) { $value = new RadixBigInteger(find(s), $s.getText().substring(2), 16); check($value); }
- | ^(OP_DEC_CONSTANT s=.) { $value = new RadixBigInteger(find(s), $s.getText()); check($value); }
- | ^(OP_BIN_CONSTANT s=.) { $value = new RadixBigInteger(find(s), $s.getText().substring(2), 2); check($value); }
+// Only make radix adjustable for the literal value, not sizes, bitranges, etc.
+int_lit returns [RadixBigInteger value]
+ : ^(OP_HEX_CONSTANT s=.) {
+ $value = RadixBigInteger.parse(input, OP_HEX_CONSTANT, find(s),
+ $s.getText().substring(2), 16);
+ check($value);
+ }
+ | ^(OP_DEC_CONSTANT s=.) {
+ $value = RadixBigInteger.parse(input, OP_DEC_CONSTANT, find(s),
+ $s.getText().substring(2), 10);
+ check($value);
+ }
+ | ^(OP_BIN_CONSTANT s=.) {
+ $value = RadixBigInteger.parse(input, OP_BIN_CONSTANT, find(s),
+ $s.getText().substring(2), 2);
+ check($value);
+ }
+ | ^(OP_DEF_CONSTANT s=.) {
+ $value = pcode.parseIntegerLiteral(find(s), $s.getText());
+ check($value);
+ }
+ ;
+
+integer returns [RadixBigInteger value]
+ : ^(OP_HEX_CONSTANT s=.) {
+ $value = RadixBigInteger.parse(input, OP_HEX_CONSTANT, find(s),
+ $s.getText().substring(2), 16);
+ check($value);
+ }
+ | ^(OP_BIN_CONSTANT s=.) {
+ $value = RadixBigInteger.parse(input, OP_BIN_CONSTANT, find(s),
+ $s.getText().substring(2), 2);
+ check($value);
+ }
+ // For sizes, bitranges, etc., default is still base 10
+ | ^(OP_DEF_CONSTANT s=.) {
+ $value = RadixBigInteger.parse(input, OP_DEC_CONSTANT, find(s), $s.getText(), 10);
+ check($value);
+ }
;
diff --git a/Ghidra/Framework/SoftwareModeling/src/main/antlr/ghidra/sleigh/grammar/SleighEcho.g b/Ghidra/Framework/SoftwareModeling/src/main/antlr/ghidra/sleigh/grammar/SleighEcho.g
index fcb42e4c19..da8e9d3bd2 100644
--- a/Ghidra/Framework/SoftwareModeling/src/main/antlr/ghidra/sleigh/grammar/SleighEcho.g
+++ b/Ghidra/Framework/SoftwareModeling/src/main/antlr/ghidra/sleigh/grammar/SleighEcho.g
@@ -493,6 +493,6 @@ identifier returns [String value]
integer returns [String value]
: ^(OP_HEX_CONSTANT s=.) { $value = $s.getText(); }
- | ^(OP_DEC_CONSTANT s=.) { $value = $s.getText(); }
| ^(OP_BIN_CONSTANT s=.) { $value = $s.getText(); }
+ | ^(OP_DEF_CONSTANT s=.) { $value = $s.getText(); }
;
diff --git a/Ghidra/Framework/SoftwareModeling/src/main/antlr/ghidra/sleigh/grammar/SleighParser.g b/Ghidra/Framework/SoftwareModeling/src/main/antlr/ghidra/sleigh/grammar/SleighParser.g
index 6beda0844a..f1209e559f 100644
--- a/Ghidra/Framework/SoftwareModeling/src/main/antlr/ghidra/sleigh/grammar/SleighParser.g
+++ b/Ghidra/Framework/SoftwareModeling/src/main/antlr/ghidra/sleigh/grammar/SleighParser.g
@@ -587,6 +587,6 @@ strict_id
integer
: lc=HEX_INT -> ^(OP_HEX_CONSTANT[$lc, "HEX_INT"] HEX_INT)
- | lc=DEC_INT -> ^(OP_DEC_CONSTANT[$lc, "DEC_INT"] DEC_INT)
+ | lc=DEF_INT -> ^(OP_DEF_CONSTANT[$lc, "DEF_INT"] DEF_INT)
| lc=BIN_INT -> ^(OP_BIN_CONSTANT[$lc, "BIN_INT"] BIN_INT)
;
diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcodeCPort/sleighbase/SleighBase.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcodeCPort/sleighbase/SleighBase.java
index 0273875dbb..357cf1262a 100644
--- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcodeCPort/sleighbase/SleighBase.java
+++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcodeCPort/sleighbase/SleighBase.java
@@ -29,13 +29,13 @@ import ghidra.pcodeCPort.space.AddrSpace;
import ghidra.pcodeCPort.space.spacetype;
import ghidra.pcodeCPort.translate.Translate;
import ghidra.program.model.pcode.Encoder;
-import ghidra.sleigh.grammar.SourceFileIndexer;
+import ghidra.sleigh.grammar.*;
public abstract class SleighBase extends Translate implements NamedSymbolProvider {
/**
- * Note: The value of {@link #MAX_UNIQUE_SIZE} must match the corresponding value
- * defined by sleighbase.cc
+ * Note: The value of {@link #MAX_UNIQUE_SIZE} must match the corresponding value defined by
+ * sleighbase.cc
*/
public static final long MAX_UNIQUE_SIZE = 256; //Maximum size of a varnode in the unique space.
//Should match value in sleighbase.cc
@@ -71,6 +71,10 @@ public abstract class SleighBase extends Translate implements NamedSymbolProvide
indexer = new SourceFileIndexer();
}
+ public RadixBigInteger parseIntegerLiteral(Location loc, String text) {
+ return new RadixBigInteger(loc, text, 10);
+ }
+
public boolean isInitialized() {
return (root != null);
}
@@ -208,5 +212,4 @@ public abstract class SleighBase extends Translate implements NamedSymbolProvide
symtab.encode(encoder);
encoder.closeElement(ELEM_SLEIGH);
}
-
}
diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcodeCPort/slgh_compile/PcodeCompile.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcodeCPort/slgh_compile/PcodeCompile.java
index 17447b9155..49c02fc51b 100644
--- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcodeCPort/slgh_compile/PcodeCompile.java
+++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcodeCPort/slgh_compile/PcodeCompile.java
@@ -32,13 +32,14 @@ import ghidra.pcodeCPort.semantics.ConstTpl.v_field;
import ghidra.pcodeCPort.slghsymbol.*;
import ghidra.pcodeCPort.space.AddrSpace;
import ghidra.sleigh.grammar.Location;
+import ghidra.sleigh.grammar.RadixBigInteger;
public abstract class PcodeCompile {
public final static Logger log = LogManager.getLogger(PcodeCompile.class);
- public VectorSTL noplist = new VectorSTL();
- private int local_labelcount;
+ public VectorSTL noplist = new VectorSTL<>();
+ private int localLabelcount;
private int errors;
private int warnings;
@@ -55,13 +56,17 @@ public abstract class PcodeCompile {
public abstract AddrSpace getConstantSpace();
+ public abstract int getDefaultConstantSize();
+
public abstract AddrSpace getUniqueSpace();
public abstract long allocateTemp();
public abstract void addSymbol(SleighSymbol sym);
- public abstract SleighSymbol findSymbol(String nm);
+ public abstract SleighSymbol findSymbol(Location loc, String nm);
+
+ public abstract RadixBigInteger parseIntegerLiteral(Location loc, String text);
public abstract SectionSymbol newSectionSymbol(Location where, String text);
@@ -117,13 +122,11 @@ public abstract class PcodeCompile {
}
public void resetLabelCount() {
- local_labelcount = 0;
+ localLabelcount = 0;
}
- private void force_size(VarnodeTpl vt, ConstTpl size, VectorSTL ops)
-
- {
-// entry("force_size", vt, size, ops);
+ private void forceSize(VarnodeTpl vt, ConstTpl size, VectorSTL ops) {
+ // entry("forceSize", vt, size, ops);
if ((vt.getSize().getType() != ConstTpl.const_type.real) || (vt.getSize().getReal() != 0)) {
return; // Size already exists
}
@@ -182,7 +185,7 @@ public abstract class PcodeCompile {
// Create a label symbol
public LabelSymbol defineLabel(Location location, String name) {
entry("defineLabel", location, name);
- LabelSymbol labsym = new LabelSymbol(location, name, local_labelcount++);
+ LabelSymbol labsym = new LabelSymbol(location, name, localLabelcount++);
addSymbol(labsym); // Add symbol to local scope
return labsym;
}
@@ -387,7 +390,7 @@ public abstract class PcodeCompile {
op.setOutput(outvn);
ptr.ops.push_back(op);
if (qual.getSize() > 0) {
- force_size(outvn, new ConstTpl(ConstTpl.const_type.real, qual.getSize()), ptr.ops);
+ forceSize(outvn, new ConstTpl(ConstTpl.const_type.real, qual.getSize()), ptr.ops);
}
ptr.outvn = new VarnodeTpl(location, outvn);
return ptr;
@@ -407,7 +410,7 @@ public abstract class PcodeCompile {
op.addInput(ptr.outvn);
op.addInput(val.outvn);
res.push_back(op);
- force_size(val.outvn, new ConstTpl(ConstTpl.const_type.real, qual.getSize()), res);
+ forceSize(val.outvn, new ConstTpl(ConstTpl.const_type.real, qual.getSize()), res);
ptr.outvn = null;
val.outvn = null;
return res;
@@ -557,7 +560,7 @@ public abstract class PcodeCompile {
}
// We know what the size of the input has to be
- force_size(rhs.outvn, new ConstTpl(ConstTpl.const_type.real, smallsize), rhs.ops);
+ forceSize(rhs.outvn, new ConstTpl(ConstTpl.const_type.real, smallsize), rhs.ops);
ExprTree res;
VarnodeTpl finalout = buildTruncatedVarnode(location, vn, bitoffset, numbits);
@@ -674,7 +677,7 @@ public abstract class PcodeCompile {
if (maskneeded) {
appendOp(location, OpCode.CPUI_INT_AND, res, mask, finalsize);
}
- force_size(res.outvn, new ConstTpl(ConstTpl.const_type.real, finalsize), res.ops);
+ forceSize(res.outvn, new ConstTpl(ConstTpl.const_type.real, finalsize), res.ops);
return res;
}
@@ -733,7 +736,7 @@ public abstract class PcodeCompile {
match = op.getIn(i);
}
if (match != null) {
- force_size(vt, match.getSize(), ops);
+ forceSize(vt, match.getSize(), ops);
}
}
@@ -743,12 +746,11 @@ public abstract class PcodeCompile {
// Right now this is written assuming operands for the constructor are
// are built before any other pcode in the constructor is generated
-// entry("fillinZero", op, ops);
+ // entry("fillinZero", op, ops);
int inputsize, i;
switch (op.getOpcode()) {
- case CPUI_COPY: // Instructions where all inputs and output are same
- // size
+ case CPUI_COPY: // Instructions where all inputs and output are same size
case CPUI_INT_ADD:
case CPUI_INT_SUB:
case CPUI_INT_2COMP:
@@ -800,7 +802,7 @@ public abstract class PcodeCompile {
case CPUI_BOOL_AND:
case CPUI_BOOL_OR:
if (op.getOut().isZeroSize()) {
- force_size(op.getOut(), new ConstTpl(ConstTpl.const_type.real, 1), ops);
+ forceSize(op.getOut(), new ConstTpl(ConstTpl.const_type.real, 1), ops);
}
inputsize = op.numInput();
for (i = 0; i < inputsize; ++i) {
@@ -816,27 +818,27 @@ public abstract class PcodeCompile {
case CPUI_INT_SRIGHT:
if (op.getOut().isZeroSize()) {
if (!op.getIn(0).isZeroSize()) {
- force_size(op.getOut(), op.getIn(0).getSize(), ops);
+ forceSize(op.getOut(), op.getIn(0).getSize(), ops);
}
}
else if (op.getIn(0).isZeroSize()) {
- force_size(op.getIn(0), op.getOut().getSize(), ops);
+ forceSize(op.getIn(0), op.getOut().getSize(), ops);
}
// fallthru to subpiece constant check
case CPUI_SUBPIECE:
if (op.getIn(1).isZeroSize()) {
- force_size(op.getIn(1), new ConstTpl(ConstTpl.const_type.real, 4), ops);
+ forceSize(op.getIn(1), new ConstTpl(ConstTpl.const_type.real, 4), ops);
}
break;
case CPUI_CPOOLREF:
if (op.getOut().isZeroSize() && (!op.getIn(0).isZeroSize())) {
- force_size(op.getOut(), op.getIn(0).getSize(), ops);
+ forceSize(op.getOut(), op.getIn(0).getSize(), ops);
}
if (op.getIn(0).isZeroSize() && (!op.getOut().isZeroSize())) {
- force_size(op.getIn(0), op.getOut().getSize(), ops);
+ forceSize(op.getIn(0), op.getOut().getSize(), ops);
}
for (i = 1; i < op.numInput(); ++i) {
- force_size(op.getIn(i), new ConstTpl(ConstTpl.const_type.real, 8), ops);
+ forceSize(op.getIn(i), new ConstTpl(ConstTpl.const_type.real, 8), ops);
}
default:
break;
diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcodeCPort/slgh_compile/SleighCompile.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcodeCPort/slgh_compile/SleighCompile.java
index 295fbbc141..bbacf5c6f1 100644
--- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcodeCPort/slgh_compile/SleighCompile.java
+++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcodeCPort/slgh_compile/SleighCompile.java
@@ -46,8 +46,8 @@ import utilities.util.FileResolutionResult;
import utilities.util.FileUtilities;
/**
- * SleighCompile provides the ability to compile Sleigh language module (e.g., *.slaspec)
- * files.
+ * SleighCompile provides the ability to compile Sleigh language module (e.g.,
+ * *.slaspec) files.
*/
public class SleighCompile extends SleighBase {
@@ -120,6 +120,11 @@ public class SleighCompile extends SleighBase {
return SleighCompile.this.getConstantSpace();
}
+ @Override
+ public int getDefaultConstantSize() {
+ return 0;
+ }
+
@Override
public AddrSpace getDefaultSpace() {
return SleighCompile.this.getDefaultSpace();
@@ -136,10 +141,15 @@ public class SleighCompile extends SleighBase {
}
@Override
- public SleighSymbol findSymbol(String nm) {
+ public SleighSymbol findSymbol(Location loc, String nm) {
return SleighCompile.this.findSymbol(nm);
}
+ @Override
+ public RadixBigInteger parseIntegerLiteral(Location loc, String text) {
+ return SleighCompile.this.parseIntegerLiteral(loc, text);
+ }
+
@Override
public long allocateTemp() {
return getUniqueAddr();
@@ -1279,11 +1289,10 @@ public class SleighCompile extends SleighBase {
public void selfDefine(OperandSymbol sym) {
entry("selfDefine", sym);
SleighSymbol sleighSymbol = symtab.findSymbol(sym.getName(), 1);
- if (!(sleighSymbol instanceof TripleSymbol)) {
+ if (!(sleighSymbol instanceof TripleSymbol glob)) {
reportError(sym.getLocation(), "No matching global symbol '" + sym.getName() + "'");
return;
}
- TripleSymbol glob = (TripleSymbol) sleighSymbol;
symbol_type tp = glob.getType();
try {
if ((tp == symbol_type.value_symbol) || (tp == symbol_type.context_symbol)) {
@@ -1587,6 +1596,7 @@ public class SleighCompile extends SleighBase {
/**
* Insert a region of zero bits into an address offset
+ *
* @param addr is the address offset
* @return the modified offset
*/
@@ -1900,9 +1910,10 @@ public class SleighCompile extends SleighBase {
}
/**
- * Run the sleigh compiler. This provides a direct means of invoking the
- * compiler without using the launcher. The full SoftwareModeling classpath
- * must be established including any dependencies.
+ * Run the sleigh compiler. This provides a direct means of invoking the compiler without using
+ * the launcher. The full SoftwareModeling classpath must be established including any
+ * dependencies.
+ *
* @param args compiler command line arguments
* @throws IOException for file access errors
* @throws RecognitionException for parsing errors
diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/lang/PcodeParser.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/lang/PcodeParser.java
index 0d7c85a56f..e897d38f08 100644
--- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/lang/PcodeParser.java
+++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/lang/PcodeParser.java
@@ -61,7 +61,6 @@ public class PcodeParser extends PcodeCompile {
private HashSet currentSymbols = new HashSet<>();
protected PcodeParser(SleighBase sleigh) {
-
this.sleigh = sleigh;
initializeSymbols();
}
@@ -73,7 +72,6 @@ public class PcodeParser extends PcodeCompile {
* @param ubase is the starting offset for allocating temporary registers
*/
public PcodeParser(SleighLanguage language, long ubase) {
-
addrFactory = language.getAddressFactory();
sleigh = new PcodeTranslate(language, ubase);
initializeSymbols();
@@ -150,7 +148,7 @@ public class PcodeParser extends PcodeCompile {
}
@Override
- public SleighSymbol findSymbol(String nm) {
+ public SleighSymbol findSymbol(Location loc, String nm) {
SleighSymbol sym = symbolMap.get(nm);
if (sym != null) {
return sym;
@@ -158,6 +156,11 @@ public class PcodeParser extends PcodeCompile {
return sleigh.findSymbol(nm);
}
+ @Override
+ public RadixBigInteger parseIntegerLiteral(Location loc, String text) {
+ return sleigh.parseIntegerLiteral(loc, text);
+ }
+
public SleighBase getSleigh() {
return sleigh;
}
@@ -167,6 +170,10 @@ public class PcodeParser extends PcodeCompile {
return sleigh.getConstantSpace();
}
+ public int getDefaultConstantSize() {
+ return 0; // No particular size. Try to resolve in context.
+ }
+
@Override
public AddrSpace getDefaultSpace() {
return sleigh.getDefaultSpace();
@@ -386,6 +393,14 @@ public class PcodeParser extends PcodeCompile {
constTpl.getHandleIndex(), select);
}
+ protected SleighLexer newSleighLexer(CharStream input) {
+ return new SleighLexer(input);
+ }
+
+ protected SleighCompiler newSleighCompiler(CommonTreeNodeStream nodes) {
+ return new SleighCompiler(nodes);
+ }
+
/**
* Compile pcode semantic statements.
*
@@ -416,7 +431,7 @@ public class PcodeParser extends PcodeCompile {
env.getLocator().registerLocation(input.getLine(), new Location(srcFile, srcLine));
- SleighLexer lex = new SleighLexer(input);
+ SleighLexer lex = newSleighLexer(input);
lex.setEnv(env);
UnbufferedTokenStream tokens = new UnbufferedTokenStream(lex);
SleighParser parser = new SleighParser(tokens);
@@ -429,7 +444,7 @@ public class PcodeParser extends PcodeCompile {
CommonTreeNodeStream nodes = new CommonTreeNodeStream(semantic.getTree());
nodes.setTokenStream(tokens);
// ANTLRUtil.debugNodeStream(nodes, System.out);
- SleighCompiler walker = new SleighCompiler(nodes);
+ SleighCompiler walker = newSleighCompiler(nodes);
SectionVector rtl = walker.semantic(env, null, this, semantic.getTree(), false, false);
diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/sleigh/grammar/AbstractSleighCompiler.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/sleigh/grammar/AbstractSleighCompiler.java
new file mode 100644
index 0000000000..bddd9a8815
--- /dev/null
+++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/sleigh/grammar/AbstractSleighCompiler.java
@@ -0,0 +1,178 @@
+/* ###
+ * 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.sleigh.grammar;
+
+import java.math.BigInteger;
+
+import org.antlr.runtime.*;
+import org.antlr.runtime.tree.*;
+
+import ghidra.pcodeCPort.slgh_compile.PcodeCompile;
+import ghidra.pcodeCPort.slgh_compile.SleighCompile;
+import ghidra.pcodeCPort.slghsymbol.*;
+
+public abstract class AbstractSleighCompiler extends TreeParser {
+
+ protected static final BigInteger MAX_ULONG = new BigInteger("ffffffffffffffff", 16);
+ protected static final BigInteger MIN_SLONG = new BigInteger("-8000000000000000", 16);
+ protected static final BigInteger MAX_UINT = new BigInteger("ffffffff", 16);
+
+ public AbstractSleighCompiler(TreeNodeStream input) {
+ super(input);
+ }
+
+ public AbstractSleighCompiler(TreeNodeStream input, RecognizerSharedState state) {
+ super(input, state);
+ }
+
+ protected ParsingEnvironment env = null;
+ protected SleighCompile sc = null;
+ protected PcodeCompile pcode = null;
+
+ public void reportError(Location loc, String msg) {
+ if (pcode != null) {
+ pcode.reportError(loc, msg);
+ }
+ else {
+ sc.reportError(loc, msg);
+ }
+ }
+
+ public void reportWarning(Location loc, String msg) {
+ if (pcode != null) {
+ pcode.reportWarning(loc, msg);
+ }
+ else {
+ sc.reportWarning(loc, msg);
+ }
+ }
+
+ public boolean passesCheck(RadixBigInteger rbi) {
+ return rbi.bitLength() <= 64;
+ }
+
+ public void check(RadixBigInteger rbi) {
+ if (!passesCheck(rbi)) {
+ reportError(rbi.location, "Integer representation exceeds Java long (" + rbi + ")");
+ }
+ }
+
+ protected long toSLong(RadixBigInteger bi) {
+ try {
+ return bi.longValueExact();
+ }
+ catch (ArithmeticException e) {
+ reportError(bi.location, "Integer cannot be represented as signed long: " + bi);
+ return bi.longValue();
+ }
+ }
+
+ protected long toULong(RadixBigInteger bi) {
+ if (bi.compareTo(MAX_ULONG) > 0 || bi.signum() < 0) {
+ reportError(bi.location, "Integer cannot be represented as unsigned long: " + bi);
+ }
+ return bi.longValue();
+ }
+
+ protected long toLong(RadixBigInteger bi) {
+ if (bi.compareTo(MAX_ULONG) > 0 || bi.compareTo(MIN_SLONG) < 0) {
+ reportError(bi.location, "Integer cannot be represented as long: " + bi);
+ }
+ return bi.longValue();
+ }
+
+ protected int toUInt(RadixBigInteger bi) {
+ if (bi.compareTo(MAX_UINT) > 0 || bi.signum() < 0) {
+ reportError(bi.location, "Integer cannot be represented as unsigned int: " + bi);
+ }
+ return bi.intValue();
+ }
+
+ protected void redefinedError(SleighSymbol sym, Tree t, String what) {
+ String msg =
+ "symbol '" + sym.getName() + "' (from " + sym.getLocation() + ") redefined as " + what;
+ reportError(find(t), msg);
+ }
+
+ protected void wildcardError(Tree t, String what) {
+ String msg = "wildcard (_) not allowed in " + what;
+ reportError(find(t), msg);
+ }
+
+ protected void wrongSymbolTypeError(SleighSymbol sym, Location where, String type,
+ String purpose) {
+ String msg = sym.getType() + " '" + sym + "' (defined at " + sym.getLocation() +
+ ") is wrong type (should be " + type + ") in " + purpose;
+ reportError(where, msg);
+ }
+
+ protected void undeclaredSymbolError(SleighSymbol sym, Location where, String purpose) {
+ String msg = "'" + sym + "' (used in " + purpose + ") is not declared in the pattern list";
+ reportError(where, msg);
+ }
+
+ protected void unknownSymbolError(String text, Location loc, String type, String purpose) {
+ String msg = "unknown " + type + " '" + text + "' in " + purpose;
+ reportError(loc, msg);
+ }
+
+ protected void invalidDynamicTargetError(Location loc, String purpose) {
+ String msg = "invalid dynamic target used in " + purpose;
+ reportError(loc, msg);
+ }
+
+ protected Location find(Tree t) {
+ return env.getLocator().getLocation(t.getLine());
+ }
+
+ protected SubtableSymbol findOrNewTable(Location loc, String name) {
+ SleighSymbol sym = sc.findSymbol(name);
+ if (sym == null) {
+ SubtableSymbol ss = sc.newTable(loc, name);
+ return ss;
+ }
+ else if (sym.getType() != symbol_type.subtable_symbol) {
+ wrongSymbolTypeError(sym, loc, "subtable", "subconstructor");
+ return null;
+ }
+ else {
+ return (SubtableSymbol) sym;
+ }
+ }
+
+ protected RadixBigInteger resolveDefaultConstant(Location loc, String text) {
+ throw new AssertionError("Implement me");
+ }
+
+ @Override
+ public String getErrorMessage(RecognitionException e, String[] tokenNames) {
+ return env.getParserErrorMessage(e, tokenNames);
+ }
+
+ @Override
+ public String getTokenErrorDisplay(Token t) {
+ return env.getTokenErrorDisplay(t);
+ }
+
+ @Override
+ public String getErrorHeader(RecognitionException e) {
+ return env.getErrorHeader(e);
+ }
+
+ void bail(String msg) {
+ throw new BailoutException(msg);
+ }
+}
diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/sleigh/grammar/RadixBigInteger.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/sleigh/grammar/RadixBigInteger.java
index 7ad4baaba2..ef3dede4fd 100644
--- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/sleigh/grammar/RadixBigInteger.java
+++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/sleigh/grammar/RadixBigInteger.java
@@ -18,11 +18,23 @@ package ghidra.sleigh.grammar;
import java.math.BigInteger;
import java.util.Random;
+import org.antlr.runtime.*;
+
public class RadixBigInteger extends BigInteger {
private static final long serialVersionUID = -7927157989937732244L;
protected int preferredRadix = 10;
public final Location location;
+ public static RadixBigInteger parse(IntStream input, int expected, Location location,
+ String val, int radix) throws RecognitionException {
+ try {
+ return new RadixBigInteger(location, val, radix);
+ }
+ catch (NumberFormatException e) {
+ throw new MismatchedTokenException(expected, input);
+ }
+ }
+
public RadixBigInteger(Location location, byte[] val) {
super(val);
this.location = location;
diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/sleigh/grammar/SleighLexer.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/sleigh/grammar/SleighLexer.java
index d9910e50a8..4958a8f480 100644
--- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/sleigh/grammar/SleighLexer.java
+++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/sleigh/grammar/SleighLexer.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.
@@ -23,6 +23,10 @@ public class SleighLexer extends LexerMultiplexer implements SleighRecognizerCon
super(new BaseLexer(input), new DisplayLexer(input), new SemanticLexer(input));
}
+ public SleighLexer(CharStream input, TokenSource semanticLexer) {
+ super(new BaseLexer(input), new DisplayLexer(input), semanticLexer);
+ }
+
public void setEnv(ParsingEnvironment env) {
for (TokenSource src : modes) {
AbstractSleighLexer lex = (AbstractSleighLexer) src;
diff --git a/Ghidra/Test/DebuggerIntegrationTest/src/test/java/ghidra/app/plugin/core/debug/gui/listing/DebuggerListingProviderTest.java b/Ghidra/Test/DebuggerIntegrationTest/src/test/java/ghidra/app/plugin/core/debug/gui/listing/DebuggerListingProviderTest.java
index 57023fd468..3e7bfd62fc 100644
--- a/Ghidra/Test/DebuggerIntegrationTest/src/test/java/ghidra/app/plugin/core/debug/gui/listing/DebuggerListingProviderTest.java
+++ b/Ghidra/Test/DebuggerIntegrationTest/src/test/java/ghidra/app/plugin/core/debug/gui/listing/DebuggerListingProviderTest.java
@@ -54,6 +54,7 @@ import ghidra.debug.api.action.AutoReadMemorySpec;
import ghidra.debug.api.control.ControlMode;
import ghidra.debug.api.tracemgr.DebuggerCoordinates;
import ghidra.framework.model.*;
+import ghidra.pcode.exec.DebuggerPcodeUtils;
import ghidra.program.model.address.*;
import ghidra.program.model.data.PointerDataType;
import ghidra.program.model.lang.Register;
diff --git a/Ghidra/Test/DebuggerIntegrationTest/src/test/java/ghidra/pcode/exec/TraceRmiPcodeExecTest.java b/Ghidra/Test/DebuggerIntegrationTest/src/test/java/ghidra/pcode/exec/TraceRmiPcodeExecTest.java
index 9d2f585d30..9c356b8f23 100644
--- a/Ghidra/Test/DebuggerIntegrationTest/src/test/java/ghidra/pcode/exec/TraceRmiPcodeExecTest.java
+++ b/Ghidra/Test/DebuggerIntegrationTest/src/test/java/ghidra/pcode/exec/TraceRmiPcodeExecTest.java
@@ -24,11 +24,15 @@ import org.junit.Test;
import db.Transaction;
import ghidra.app.plugin.core.debug.gui.AbstractGhidraHeadedDebuggerIntegrationTest;
+import ghidra.app.plugin.processors.sleigh.SleighException;
import ghidra.app.plugin.processors.sleigh.SleighLanguage;
import ghidra.debug.api.target.Target;
import ghidra.debug.api.tracemgr.DebuggerCoordinates;
import ghidra.pcode.exec.PcodeArithmetic.Purpose;
+import ghidra.pcode.exec.SleighUtils.LitIdMode;
import ghidra.program.model.lang.RegisterValue;
+import ghidra.program.model.symbol.SourceType;
+import ghidra.trace.database.symbol.DBTraceSymbolManager;
import ghidra.trace.model.Lifespan;
import ghidra.trace.model.memory.TraceMemorySpace;
import ghidra.trace.model.stack.TraceStackFrame;
@@ -52,6 +56,11 @@ public class TraceRmiPcodeExecTest extends AbstractGhidraHeadedDebuggerIntegrati
tb.createObjectsProcessAndThreads();
thread = tb.obj("Processes[1].Threads[1]").queryInterface(TraceThread.class);
tb.createObjectsFramesAndRegs(thread, Lifespan.nowOn(0), tb.host, 1);
+
+ DBTraceSymbolManager syms = tb.trace.getSymbolManager();
+ syms.labels()
+ .create(0, tb.addr(0x1234), "abba", syms.getGlobalNamespace(),
+ SourceType.IMPORTED);
}
target = rmiCx.publishTarget(tool, tb.trace);
language = (SleighLanguage) tb.trace.getBaseLanguage();
@@ -84,6 +93,174 @@ public class TraceRmiPcodeExecTest extends AbstractGhidraHeadedDebuggerIntegrati
executor.getArithmetic().toBigInteger(result, Purpose.INSPECT));
}
+ @Test
+ public void testExecutorEvalBinLit() throws Throwable {
+ setupExecTest();
+
+ DebuggerCoordinates coords = DebuggerCoordinates.NOWHERE.target(target).thread(thread);
+ PcodeExpression expr = DebuggerPcodeUtils.compileExpression(tool, coords, tb.addr(0x1000),
+ ".+0b10", LitIdMode.NORMAL);
+ PcodeExecutor executor = DebuggerPcodeUtils.executorForCoordinates(tool, coords);
+ byte[] result = expr.evaluate(executor);
+ assertEquals(new BigInteger("1002", 16),
+ executor.getArithmetic().toBigInteger(result, Purpose.INSPECT));
+ }
+
+ @Test
+ public void testExecutorEvalWithDot() throws Throwable {
+ setupExecTest();
+
+ DebuggerCoordinates coords = DebuggerCoordinates.NOWHERE.target(target).thread(thread);
+ PcodeExpression expr =
+ DebuggerPcodeUtils.compileExpression(tool, coords, tb.addr(0x1000), ".+4");
+ PcodeExecutor executor = DebuggerPcodeUtils.executorForCoordinates(tool, coords);
+ byte[] result = expr.evaluate(executor);
+ assertEquals(new BigInteger("1004", 16),
+ executor.getArithmetic().toBigInteger(result, Purpose.INSPECT));
+ }
+
+ @Test
+ public void testExecutorEvalWithLabel() throws Throwable {
+ setupExecTest();
+
+ DebuggerCoordinates coords = DebuggerCoordinates.NOWHERE.target(target).thread(thread);
+ PcodeExpression expr =
+ DebuggerPcodeUtils.compileExpression(tool, coords, tb.addr(0x1000), "abba+4");
+ PcodeExecutor executor = DebuggerPcodeUtils.executorForCoordinates(tool, coords);
+ byte[] result = expr.evaluate(executor);
+ assertEquals(new BigInteger("1238", 16),
+ executor.getArithmetic().toBigInteger(result, Purpose.INSPECT));
+ }
+
+ @Test
+ public void testExecutorEvalHexMode() throws Throwable {
+ setupExecTest();
+
+ DebuggerCoordinates coords = DebuggerCoordinates.NOWHERE.target(target).thread(thread);
+ PcodeExpression expr = DebuggerPcodeUtils.compileExpression(tool, coords, tb.addr(0x1000),
+ ".+4c", LitIdMode.HEX);
+ PcodeExecutor executor = DebuggerPcodeUtils.executorForCoordinates(tool, coords);
+ byte[] result = expr.evaluate(executor);
+ assertEquals(new BigInteger("104c", 16),
+ executor.getArithmetic().toBigInteger(result, Purpose.INSPECT));
+ }
+
+ @Test
+ public void testExecutorEvalHexMode0nPrefix() throws Throwable {
+ setupExecTest();
+
+ DebuggerCoordinates coords = DebuggerCoordinates.NOWHERE.target(target).thread(thread);
+ PcodeExpression expr = DebuggerPcodeUtils.compileExpression(tool, coords, tb.addr(0x1000),
+ ".+0n100", LitIdMode.HEX);
+ PcodeExecutor executor = DebuggerPcodeUtils.executorForCoordinates(tool, coords);
+ byte[] result = expr.evaluate(executor);
+ assertEquals(new BigInteger("1064", 16),
+ executor.getArithmetic().toBigInteger(result, Purpose.INSPECT));
+ }
+
+ @Test
+ public void testExecutorEvalHexModeWithSize() throws Throwable {
+ setupExecTest();
+
+ DebuggerCoordinates coords = DebuggerCoordinates.NOWHERE.target(target).thread(thread);
+ PcodeExpression expr = DebuggerPcodeUtils.compileExpression(tool, coords, tb.addr(0x1000),
+ ".+4c:8", LitIdMode.HEX);
+ PcodeExecutor executor = DebuggerPcodeUtils.executorForCoordinates(tool, coords);
+ byte[] result = expr.evaluate(executor);
+ assertEquals(new BigInteger("104c", 16),
+ executor.getArithmetic().toBigInteger(result, Purpose.INSPECT));
+ }
+
+ @Test(expected = SleighException.class)
+ public void testExecutorEvalHexModeWithHexSizeErr() throws Throwable {
+ setupExecTest();
+
+ DebuggerCoordinates coords = DebuggerCoordinates.NOWHERE.target(target).thread(thread);
+ PcodeExpression expr = DebuggerPcodeUtils.compileExpression(tool, coords, tb.addr(0x1000),
+ ".+4c:a", LitIdMode.HEX);
+ PcodeExecutor executor = DebuggerPcodeUtils.executorForCoordinates(tool, coords);
+ byte[] result = expr.evaluate(executor);
+ assertEquals(new BigInteger("104c", 16),
+ executor.getArithmetic().toBigInteger(result, Purpose.INSPECT));
+ }
+
+ @Test
+ public void testExecutorEvalHexModeLooksBinPrefix() throws Throwable {
+ setupExecTest();
+
+ DebuggerCoordinates coords = DebuggerCoordinates.NOWHERE.target(target).thread(thread);
+ PcodeExpression expr = DebuggerPcodeUtils.compileExpression(tool, coords, tb.addr(0x1000),
+ ".+0b12", LitIdMode.HEX);
+ PcodeExecutor executor = DebuggerPcodeUtils.executorForCoordinates(tool, coords);
+ byte[] result = expr.evaluate(executor);
+ assertEquals(new BigInteger("1b12", 16),
+ executor.getArithmetic().toBigInteger(result, Purpose.INSPECT));
+ }
+
+ @Test
+ public void testExecutorEvalHexModeLooksBin() throws Throwable {
+ setupExecTest();
+
+ DebuggerCoordinates coords = DebuggerCoordinates.NOWHERE.target(target).thread(thread);
+ PcodeExpression expr = DebuggerPcodeUtils.compileExpression(tool, coords, tb.addr(0x1000),
+ ".+0b10", LitIdMode.HEX);
+ PcodeExecutor executor = DebuggerPcodeUtils.executorForCoordinates(tool, coords);
+ byte[] result = expr.evaluate(executor);
+ assertEquals(new BigInteger("1b10", 16),
+ executor.getArithmetic().toBigInteger(result, Purpose.INSPECT));
+ }
+
+ @Test
+ public void testExecutorEvalHexModeWithLabel() throws Throwable {
+ setupExecTest();
+
+ DebuggerCoordinates coords = DebuggerCoordinates.NOWHERE.target(target).thread(thread);
+ PcodeExpression expr = DebuggerPcodeUtils.compileExpression(tool, coords, tb.addr(0x1000),
+ "abba+4", LitIdMode.HEX);
+ PcodeExecutor executor = DebuggerPcodeUtils.executorForCoordinates(tool, coords);
+ byte[] result = expr.evaluate(executor);
+ // This should prefer to interpret abba as an int (hex) literal
+ assertEquals(new BigInteger("abbe", 16),
+ executor.getArithmetic().toBigInteger(result, Purpose.INSPECT));
+ }
+
+ @Test
+ public void testExecutorEvalIdHexModeWithLabel() throws Throwable {
+ setupExecTest();
+
+ DebuggerCoordinates coords = DebuggerCoordinates.NOWHERE.target(target).thread(thread);
+ PcodeExpression expr = DebuggerPcodeUtils.compileExpression(tool, coords, tb.addr(0x1000),
+ "abba+4", LitIdMode.ID_HEX);
+ PcodeExecutor executor = DebuggerPcodeUtils.executorForCoordinates(tool, coords);
+ byte[] result = expr.evaluate(executor);
+ // This should prefer to interpret abba as an id (with value 0x1234)
+ assertEquals(new BigInteger("1238", 16),
+ executor.getArithmetic().toBigInteger(result, Purpose.INSPECT));
+ }
+
+ @Test
+ public void testExecutorEvalIdHexModeWithHexLooksLabel() throws Throwable {
+ setupExecTest();
+
+ DebuggerCoordinates coords = DebuggerCoordinates.NOWHERE.target(target).thread(thread);
+ PcodeExpression expr = DebuggerPcodeUtils.compileExpression(tool, coords, tb.addr(0x1000),
+ "abbb+4", LitIdMode.ID_HEX);
+ PcodeExecutor executor = DebuggerPcodeUtils.executorForCoordinates(tool, coords);
+ byte[] result = expr.evaluate(executor);
+ // Even though abbb may be parsed as an id, we fall back to an int, if hex.
+ assertEquals(new BigInteger("abbf", 16),
+ executor.getArithmetic().toBigInteger(result, Purpose.INSPECT));
+ }
+
+ @Test(expected = SleighException.class)
+ public void testExecutorEvalNormalModeHexErr() throws Throwable {
+ setupExecTest();
+
+ DebuggerCoordinates coords = DebuggerCoordinates.NOWHERE.target(target).thread(thread);
+ DebuggerPcodeUtils.compileExpression(tool, coords, tb.addr(0x1000),
+ ".+4c", LitIdMode.NORMAL);
+ }
+
@Test
public void testExecutorEvalInScratchModeReadsLive() throws Throwable {
setupExecTest();