use of org.mapleir.ir.code.expr.VarExpr in project maple-ir by LLVM-but-worse.
the class PoolLocalValueResolver method getValues.
@Override
public TaintableSet<Expr> getValues(ControlFlowGraph cfg, Local l) {
if (cfg.getLocals() != pool) {
throw new UnsupportedOperationException();
}
AbstractCopyStmt copy = pool.defs.get(l);
TaintableSet<Expr> set = new TaintableSet<>();
if (copy.getOpcode() == Opcode.PHI_STORE) {
// checkRecursive(l);
// PhiExpr phi = ((CopyPhiStmt) copy).getExpression();
/*for(Expr e : phi.getArguments().values()) {
if(e.getOpcode() == Opcode.LOCAL_LOAD) {
Local l2 = ((VarExpr) e).getLocal();
if(l2 == l) {
throw new RuntimeException(copy.toString());
}
}
}*/
// set.addAll(phi.getArguments().values());
} else {
// set.add(copy.getExpression());
}
set.add(copy.getExpression());
return set;
}
use of org.mapleir.ir.code.expr.VarExpr in project maple-ir by LLVM-but-worse.
the class ConstantParameterPass method inlineConstant.
private void inlineConstant(ControlFlowGraph cfg, int argLocalIndex, Object o) {
/* we don't actually demote the synthetic copy
* here as we would also need to change the
* method desc and we can't do that until
* later so we defer it. */
LocalsPool pool = cfg.getLocals();
/* create the spill variable but not the
* actual definition yet. */
VersionedLocal argLocal = pool.get(argLocalIndex, 0, false);
VersionedLocal spill = pool.makeLatestVersion(argLocal);
AbstractCopyStmt synthParamCopy = pool.defs.get(argLocal);
ConstantExpr rhsVal = new ConstantExpr(o, synthParamCopy.getType() == Type.BOOLEAN_TYPE ? Type.BYTE_TYPE : synthParamCopy.getType());
/* we have to maintain local references in
* phis as opposed to direct constant refs,
* so we go through every use of the argLocal
* and either replace it with the constant or
* a reference to the spill local if it is in
* a phi. */
Set<VarExpr> spillUses = new HashSet<>();
boolean requireSpill = false;
Iterator<VarExpr> it = pool.uses.get(argLocal).iterator();
while (it.hasNext()) {
VarExpr v = it.next();
if (v.getParent() == null) {
/* the use is in a phi, we can't
* remove the def.
*
* we also replace the old var
* with the new spill one so we
* have to add this as a use of
* the new spill local. */
spillUses.add(v);
v.setLocal(spill);
requireSpill = true;
} else {
CodeUnit par = v.getParent();
par.overwrite(rhsVal.copy(), par.indexOf(v));
}
/* this use is no longer associated
* with the old argLocal. */
it.remove();
}
if (pool.uses.get(argLocal).size() != 0) {
throw new IllegalStateException(String.format("l:%s, uses:%s", argLocal, pool.uses.get(argLocal)));
}
if (requireSpill) {
/* generate the copy for the spill (v = const) */
CopyVarStmt spillCopy = new CopyVarStmt(new VarExpr(spill, synthParamCopy.getVariable().getType()), rhsVal);
synthParamCopy.getBlock().add(spillCopy);
/* initialise data entries for the new spill
* variable. */
pool.defs.put(spill, spillCopy);
pool.uses.put(spill, spillUses);
}
}
use of org.mapleir.ir.code.expr.VarExpr in project maple-ir by LLVM-but-worse.
the class DeadCodeEliminationPass method process.
public void process(ControlFlowGraph cfg) {
LocalsPool lp = cfg.getLocals();
boolean c;
do {
c = false;
SimpleDfs<BasicBlock> dfs = new SimpleDfs<>(cfg, cfg.getEntries().iterator().next(), SimpleDfs.PRE);
List<BasicBlock> pre = dfs.getPreOrder();
for (BasicBlock b : new HashSet<>(cfg.vertices())) {
if (!pre.contains(b)) {
// System.out.println("proc1: " + b);
for (FlowEdge<BasicBlock> fe : new HashSet<>(cfg.getEdges(b))) {
cfg.exciseEdge(fe);
}
// System.out.println("removed: ");
for (Stmt stmt : b) {
// System.out.println(" " + (b.indexOf(stmt)) + ". " + stmt);
if (stmt instanceof AbstractCopyStmt) {
AbstractCopyStmt copy = (AbstractCopyStmt) stmt;
lp.defs.remove(copy.getVariable().getLocal());
// System.out.println(" kill1 " + copy.getVariable().getLocal());
}
for (Expr e : stmt.enumerateOnlyChildren()) {
if (e.getOpcode() == Opcode.LOCAL_LOAD) {
VarExpr v = (VarExpr) e;
lp.uses.get(v.getLocal()).remove(v);
// System.out.println(" kill2 " + v.getLocal());
}
}
}
cfg.removeVertex(b);
deadBlocks++;
c = true;
} else {
// System.out.println("proc2: " + b);
UnconditionalJumpEdge<BasicBlock> uncond = null;
for (FlowEdge<BasicBlock> fe : cfg.getEdges(b)) {
if (fe.getType() == FlowEdges.UNCOND) {
uncond = (UnconditionalJumpEdge<BasicBlock>) fe;
}
}
if (uncond != null) {
BasicBlock dst = uncond.dst();
List<BasicBlock> verts = new ArrayList<>(cfg.vertices());
if (verts.indexOf(b) + 1 == verts.indexOf(dst)) {
ImmediateEdge<BasicBlock> im = new ImmediateEdge<>(b, dst);
cfg.exciseEdge(uncond);
cfg.addEdge(b, im);
Stmt stmt = b.remove(b.size() - 1);
if (stmt.getOpcode() != Opcode.UNCOND_JUMP) {
throw new IllegalStateException(b + " : " + stmt);
}
immediateJumps++;
c = true;
}
}
// if(cfg.getMethod().toString().equals("cf.k(IIIIII)V")) {}
Iterator<Stmt> it = b.iterator();
while (it.hasNext()) {
Stmt stmt = it.next();
if (stmt.getOpcode() == Opcode.LOCAL_STORE) {
AbstractCopyStmt copy = (AbstractCopyStmt) stmt;
if (copy.isSynthetic()) {
continue;
}
Local l = copy.getVariable().getLocal();
LocalsPool pool = cfg.getLocals();
// System.out.println("copy: "+ copy);
if (!ConstraintUtil.isUncopyable(copy.getExpression()) && pool.uses.get(l).size() == 0) {
for (Expr e : copy.getExpression().enumerateWithSelf()) {
if (e.getOpcode() == Opcode.LOCAL_LOAD) {
VarExpr v = (VarExpr) e;
Local l2 = v.getLocal();
pool.uses.remove(l2);
}
}
pool.uses.remove(l);
pool.defs.remove(l);
it.remove();
deadLocals++;
c = true;
}
} else if (stmt.getOpcode() == Opcode.NOP) {
it.remove();
c = true;
}
}
}
}
// for now
} while (c);
}
use of org.mapleir.ir.code.expr.VarExpr in project maple-ir by LLVM-but-worse.
the class LiftConstructorCallsPass method tryLift.
private boolean tryLift(MethodNode m, ControlFlowGraph cfg) {
Local lvar0_0 = cfg.getLocals().get(0, 0, false);
/* only contains synthetic copies */
BasicBlock entry = cfg.getEntries().iterator().next();
for (BasicBlock b : cfg.vertices()) {
for (Stmt stmt : b) {
for (Expr e : stmt.enumerateOnlyChildren()) {
if (e.getOpcode() == INVOKE) {
InvocationExpr invoke = (InvocationExpr) e;
if (invoke.getOwner().equals(m.owner.superName) && invoke.getName().equals("<init>")) {
Expr p1 = invoke.getPhysicalReceiver();
if (p1.getOpcode() == LOCAL_LOAD && ((VarExpr) p1).getLocal() == lvar0_0) {
Set<FlowEdge<BasicBlock>> predsEdges = cfg.getReverseEdges(b);
FlowEdge<BasicBlock> incoming;
if (predsEdges.size() == 1 && ((incoming = predsEdges.iterator().next()).getType() == FlowEdges.IMMEDIATE) && incoming.src() == entry) {
// BasicBlock liftBlock = new BasicBlock(cfg, cfg.vertices().size() + 1, new LabelNode());
/* split the block before the invocation and
* insert a new block. */
split(cfg, b, stmt);
return true;
} else {
System.err.printf(" warn(nolift) for %s in %n%s%n", invoke, ControlFlowGraph.printBlock(b));
System.err.printf(" preds: %s%n", predsEdges);
}
} else {
throw new IllegalStateException(String.format("broken super call: %s", invoke));
}
}
}
}
}
}
return false;
}
use of org.mapleir.ir.code.expr.VarExpr in project maple-ir by LLVM-but-worse.
the class ExpressionEvaluator method evalPossibleValues0.
private TaintableSet<ConstantExpr> evalPossibleValues0(NullPermeableHashMap<ControlFlowGraph, Set<Local>> visited, LocalValueResolver resolver, Expr e) {
if (e.getOpcode() == CONST_LOAD) {
TaintableSet<ConstantExpr> set = new TaintableSet<>();
set.add((ConstantExpr) e);
return set;
} else /*else if(e.getOpcode() == PHI) {
PhiExpr phi = (PhiExpr) e;
TaintableSet<ConstantExpr> set = new HashSet<>();
for(Expr pA : phi.getArguments().values()) {
TaintableSet<ConstantExpr> s = evalPossibleValues(resolver, pA);
set.union(s);
}
return set;
}*/
if (e.getOpcode() == ARITHMETIC) {
ArithmeticExpr ae = (ArithmeticExpr) e;
Expr l = ae.getLeft();
Expr r = ae.getRight();
TaintableSet<ConstantExpr> le = evalPossibleValues0(visited, resolver, l);
TaintableSet<ConstantExpr> re = evalPossibleValues0(visited, resolver, r);
TaintableSet<ConstantExpr> results = new TaintableSet<>(le.isTainted() | re.isTainted());
for (Iterator<Pair<ConstantExpr, ConstantExpr>> it = le.product(re); it.hasNext(); ) {
Pair<ConstantExpr, ConstantExpr> lcrc = it.next();
ConstantExpr lc = lcrc.getKey();
ConstantExpr rc = lcrc.getValue();
EvaluationFunctor<Number> b = factory.arithmetic(lc.getType(), rc.getType(), ae.getType(), ae.getOperator());
results.add(new ConstantExpr(b.eval(lc.getConstant(), rc.getConstant())));
}
return results;
} else if (e.getOpcode() == NEGATE) {
NegationExpr neg = (NegationExpr) e;
TaintableSet<ConstantExpr> inputs = evalPossibleValues0(visited, resolver, neg.getExpression());
TaintableSet<ConstantExpr> outputs = new TaintableSet<>(inputs.isTainted());
for (ConstantExpr c : inputs) {
EvaluationFunctor<Number> b = factory.negate(c.getType());
outputs.add(new ConstantExpr(b.eval(c.getConstant())));
}
return outputs;
} else if (e.getOpcode() == LOCAL_LOAD) {
VarExpr v = (VarExpr) e;
Local l = v.getLocal();
ControlFlowGraph g = e.getBlock().getGraph();
visited.getNonNull(g).add(l);
TaintableSet<Expr> defExprs = resolver.getValues(g, l);
TaintableSet<ConstantExpr> vals = new TaintableSet<>(defExprs.isTainted());
for (Expr defE : defExprs) {
if (defE.getOpcode() == LOCAL_LOAD) {
VarExpr v2 = (VarExpr) defE;
Local l2 = v2.getLocal();
if (visited.getNonNull(g).contains(l2)) {
continue;
}
visited.getNonNull(g).add(l2);
}
TaintableSet<ConstantExpr> defConstVals = evalPossibleValues0(visited, resolver, defE);
vals.union(defConstVals);
}
return vals;
} else if (e.getOpcode() == CAST) {
CastExpr cast = (CastExpr) e;
TaintableSet<ConstantExpr> inputs = evalPossibleValues0(visited, resolver, cast.getExpression());
TaintableSet<ConstantExpr> outputs = new TaintableSet<>(inputs.isTainted());
for (ConstantExpr ce : inputs) {
// TODO: czech out::
// can get expressions like (double)({lvar7_1 * 4})
// where {lvar7_1 * 4} has type INT but the real
// eval consts are all bytes or shorts etc
/*if(!ce.getType().equals(cast.getExpression().getType())) {
System.err.printf("want to cast %s%n", cast);
System.err.printf(" in: %s, death: %s%n", set, ce);
throw new IllegalStateException(ce.getType() + " : " + cast.getExpression().getType());
}*/
Type from = ce.getType();
Type to = cast.getType();
boolean p1 = TypeUtils.isPrimitive(from);
boolean p2 = TypeUtils.isPrimitive(to);
if (p1 != p2) {
throw new IllegalStateException(from + " to " + to);
}
if (!p1 && !p2) {
throw new IllegalStateException(from + " to " + to);
// return new TaintableSet<>();
}
EvaluationFunctor<Number> b = factory.cast(from, to);
outputs.add(new ConstantExpr(b.eval(ce.getConstant())));
}
return outputs;
} else if (e.getOpcode() == COMPARE) {
// throw new UnsupportedOperationException("todo lmao");
// ComparisonExpr comp = (ComparisonExpr) e;
// Expr l = comp.getLeft();
// Expr r = comp.getRight();
//
// Expr le = eval(pool, l);
// Expr re = eval(pool, r);
//
// if(le != null && re != null) {
// ConstantExpr lc = (ConstantExpr) le;
// ConstantExpr rc = (ConstantExpr) re;
//
// Bridge b = getComparisonBridge(lc.getType(), rc.getType(), comp.getComparisonType());
//
// System.out.println(b.method);
// System.out.println(comp + " -> " + b.eval(lc.getConstant(), rc.getConstant()));
// ConstantExpr cr = new ConstantExpr((int)b.eval(lc.getConstant(), rc.getConstant()));
// return cr;
// }
}
/* uncomputable value, i.e. non const. */
return new TaintableSet<>(true);
}
Aggregations