GP-3161: Some emulation framework improvements.

This commit is contained in:
Dan 2023-03-03 13:55:54 -05:00
parent a9baf9f6d8
commit 2b6ea93c9c
18 changed files with 112 additions and 45 deletions

View File

@ -99,7 +99,7 @@ public class DemoPcodeUseropLibrary extends AnnotatedPcodeUseropLibrary<byte[]>
*/
public class DemoStructuredPart extends StructuredSleigh {
final Var RAX = lang("RAX", type("long"));
final Var RCX = lang("RAX", type("byte *"));
final Var RCX = lang("RCX", type("byte *"));
final UseropDecl emu_swi = userop(type("void"), "emu_swi", List.of());
protected DemoStructuredPart(CompilerSpec cs) {

View File

@ -22,7 +22,7 @@ import ghidra.program.model.data.DataType;
* An assignment statement
*/
class AssignStmt extends AbstractStmt implements RValInternal, StmtWithVal {
private final LValInternal lhs;
final LValInternal lhs;
private final RValInternal rhs;
private final DataType type;
@ -51,9 +51,9 @@ class AssignStmt extends AbstractStmt implements RValInternal, StmtWithVal {
@Override
protected StringTree generate(Label next, Label fall) {
StringTree st = new StringTree();
st.append(lhs.generate());
st.append(lhs.generate(this));
st.append(" = ");
st.append(rhs.generate());
st.append(rhs.generate(this));
st.append(";\n");
st.append(next.genGoto(fall));
return st;
@ -65,7 +65,7 @@ class AssignStmt extends AbstractStmt implements RValInternal, StmtWithVal {
}
@Override
public String generate() {
return lhs.generate();
public StringTree generate(RValInternal parent) {
return lhs.generate(this);
}
}

View File

@ -41,7 +41,15 @@ class BinExpr extends Expr {
}
@Override
public String generate() {
return "(" + lhs.generate() + " " + op + " " + rhs.generate() + ")";
public StringTree generate(RValInternal parent) {
StringTree st = new StringTree();
st.append("(");
st.append(lhs.generate(this));
st.append(" ");
st.append(op);
st.append(" ");
st.append(rhs.generate(this));
st.append(")");
return st;
}
}

View File

@ -64,8 +64,21 @@ public class CallExpr extends Expr {
}
@Override
public String generate() {
return userop.getName() + "(" +
args.stream().map(a -> a.generate()).collect(Collectors.joining(",")) + ")";
public StringTree generate(RValInternal parent) {
StringTree st = new StringTree();
st.append(userop.getName());
st.append("(");
boolean first = false;
for (RValInternal a : args) {
if (!first) {
first = true;
}
else {
st.append(",");
}
st.append(a.generate(this));
}
st.append(")");
return st;
}
}

View File

@ -114,7 +114,7 @@ class DefaultVar implements LValInternal, Var {
}
@Override
public String generate() {
return name;
public StringTree generate(RValInternal parent) {
return StringTree.single(name);
}
}

View File

@ -45,10 +45,29 @@ class DerefExpr extends Expr implements LValInternal {
}
@Override
public String generate() {
String spacePiece =
ctx.language.getDefaultSpace() == space ? "" : ("[" + space.getName() + "]");
String sizePiece = type.getLength() == 0 ? "" : (":" + type.getLength());
return "(*" + spacePiece + sizePiece + " " + addr.generate() + ")";
public StringTree generate(RValInternal parent) {
StringTree st = new StringTree();
boolean useParens = !(parent instanceof AssignStmt as && as.lhs == this);
if (useParens) {
st.append("(*");
}
else {
st.append("*");
}
if (ctx.language.getDefaultSpace() != space) {
st.append("[");
st.append(space.getName());
st.append("]");
}
if (type.getLength() != 0) {
st.append(":");
st.append(Integer.toString(type.getLength()));
}
st.append(" ");
st.append(addr.generate(this));
if (useParens) {
st.append(")");
}
return st;
}
}

View File

@ -19,12 +19,12 @@ import ghidra.pcode.struct.StructuredSleigh.LVal;
import ghidra.program.model.data.*;
class FieldExpr extends Expr implements LValInternal {
private final RValInternal parent;
private final RValInternal composite;
private final int offset;
private FieldExpr(StructuredSleigh ctx, RValInternal parent, int offset, DataType type) {
private FieldExpr(StructuredSleigh ctx, RValInternal composite, int offset, DataType type) {
super(ctx, type);
this.parent = parent;
this.composite = composite;
this.offset = offset;
}
@ -38,16 +38,22 @@ class FieldExpr extends Expr implements LValInternal {
@Override
public LVal cast(DataType type) {
return new FieldExpr(ctx, parent, offset, type);
return new FieldExpr(ctx, composite, offset, type);
}
@Override
public String toString() {
return "<Field " + parent + " + 0x" + Long.toString(offset, 16) + ">";
return "<Field " + composite + " + 0x" + Long.toString(offset, 16) + ">";
}
@Override
public String generate() {
return "(" + parent.generate() + " + " + offset + ")";
public StringTree generate(RValInternal parent) {
StringTree st = new StringTree();
st.append("(");
st.append(composite.generate(this));
st.append(" + ");
st.append(Integer.toString(offset));
st.append(")");
return st;
}
}

View File

@ -19,7 +19,6 @@ import ghidra.pcode.struct.StructuredSleigh.Label;
import ghidra.pcode.struct.StructuredSleigh.RVal;
public class GotoStmt extends AbstractStmt {
private final RValInternal target;
protected GotoStmt(StructuredSleigh ctx, RVal target) {
@ -31,9 +30,8 @@ public class GotoStmt extends AbstractStmt {
protected StringTree generate(Label next, Label fall) {
StringTree st = new StringTree();
st.append("goto [");
st.append(target.generate());
st.append(target.generate(null));
st.append("];\n");
return st;
}
}

View File

@ -46,7 +46,15 @@ class IndexExpr extends Expr implements LValInternal {
}
@Override
public String generate() {
return "(" + base.generate() + " + (" + index.generate() + "*" + elemLen + "))";
public StringTree generate(RValInternal parent) {
StringTree st = new StringTree();
st.append("(");
st.append(base.generate(this));
st.append(" + (");
st.append(index.generate(this));
st.append("*");
st.append(Integer.toString(elemLen));
st.append("))");
return st;
}
}

View File

@ -39,7 +39,7 @@ class LiteralExpr extends Expr {
}
@Override
public String generate() {
return "0x" + Long.toHexString(val) + ":" + size;
public StringTree generate(RValInternal parent) {
return StringTree.single(String.format("0x%x:%d", val, size));
}
}

View File

@ -26,7 +26,7 @@ interface RValInternal extends RVal {
@Override
DataType getType();
String generate();
StringTree generate(RValInternal parent);
@Override
default LVal deref() {

View File

@ -37,7 +37,14 @@ public class RawExpr extends Expr {
}
@Override
public String generate() {
return "(" + expr + ")";
public StringTree generate(RValInternal parent) {
if (parent instanceof AssignStmt as && as.lhs == this) {
return StringTree.single(expr);
}
StringTree st = new StringTree();
st.append("(");
st.append(expr);
st.append(")");
return st;
}
}

View File

@ -40,7 +40,7 @@ class ResultStmt extends AbstractStmt {
StringTree st = new StringTree();
st.append(SleighPcodeUseropDefinition.OUT_SYMBOL_NAME);
st.append(" = ");
st.append(result.generate());
st.append(result.generate(null));
st.append(";\n");
st.append(routine.lReturn.genGoto(fall));
return st;

View File

@ -30,7 +30,7 @@ class ReturnStmt extends AbstractStmt {
protected StringTree generate(Label next, Label fall) {
StringTree st = new StringTree();
st.append("return [");
st.append(target.generate());
st.append(target.generate(null));
st.append("];\n");
return st;
}

View File

@ -94,7 +94,7 @@ import utilities.util.AnnotationUtilities;
* }
* };
*
* SleighPcodeUseropDefinition<Object> myUserop = ss.generate().get("my_userop");
* SleighPcodeUseropDefinition&lt;Object&gt; myUserop = ss.generate().get("my_userop");
* // To print source
* myUserop.getLines().forEach(System.out::print);
*
@ -1081,7 +1081,7 @@ public class StructuredSleigh {
}
StringTree st = new StringTree();
st.append("if ");
st.append(((RValInternal) cond).generate());
st.append(((RValInternal) cond).generate(null));
st.append(" ");
st.append(genGoto(fall));
return st;

View File

@ -39,7 +39,12 @@ class UnExpr extends Expr {
}
@Override
public String generate() {
return "(" + op + u.generate() + ")";
public StringTree generate(RValInternal parent) {
StringTree st = new StringTree();
st.append("(");
st.append(op);
st.append(u.generate(this));
st.append(")");
return st;
}
}

View File

@ -45,7 +45,7 @@ class VoidExprStmt extends AbstractStmt implements RValInternal, StmtWithVal {
@Override
protected StringTree generate(Label next, Label fall) {
StringTree st = new StringTree();
st.append(expr.generate());
st.append(expr.generate(this));
st.append(";\n");
st.append(next.genGoto(fall));
return st;
@ -57,7 +57,7 @@ class VoidExprStmt extends AbstractStmt implements RValInternal, StmtWithVal {
}
@Override
public String generate() {
return ctx.nil.generate();
public StringTree generate(RValInternal parent) {
return ctx.nil.generate(this);
}
}

View File

@ -355,7 +355,10 @@ public class DefaultPcodeThread<T> implements PcodeThread<T> {
@Override
public void overrideContextWithDefault() {
if (contextreg != Register.NO_CONTEXT) {
overrideContext(defaultContext.getDefaultValue(contextreg, counter));
RegisterValue defaultValue = defaultContext.getDefaultValue(contextreg, counter);
if (defaultValue != null) {
overrideContext(defaultValue);
}
}
}