Search in sources :

Example 31 with VarExpr

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;
}
Also used : VarExpr(org.mapleir.ir.code.expr.VarExpr) Expr(org.mapleir.ir.code.Expr) PhiExpr(org.mapleir.ir.code.expr.PhiExpr) AbstractCopyStmt(org.mapleir.ir.code.stmt.copy.AbstractCopyStmt) TaintableSet(org.mapleir.stdlib.collections.taint.TaintableSet)

Example 32 with VarExpr

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);
    }
}
Also used : VersionedLocal(org.mapleir.ir.locals.impl.VersionedLocal) LocalsPool(org.mapleir.ir.locals.LocalsPool) CopyVarStmt(org.mapleir.ir.code.stmt.copy.CopyVarStmt) ConstantExpr(org.mapleir.ir.code.expr.ConstantExpr) AbstractCopyStmt(org.mapleir.ir.code.stmt.copy.AbstractCopyStmt) VarExpr(org.mapleir.ir.code.expr.VarExpr) HashSet(java.util.HashSet) CodeUnit(org.mapleir.ir.code.CodeUnit)

Example 33 with VarExpr

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);
}
Also used : ImmediateEdge(org.mapleir.flowgraph.edges.ImmediateEdge) BasicBlock(org.mapleir.ir.cfg.BasicBlock) ArrayList(java.util.ArrayList) Local(org.mapleir.ir.locals.Local) SimpleDfs(org.mapleir.stdlib.collections.graph.algorithms.SimpleDfs) Stmt(org.mapleir.ir.code.Stmt) AbstractCopyStmt(org.mapleir.ir.code.stmt.copy.AbstractCopyStmt) LocalsPool(org.mapleir.ir.locals.LocalsPool) VarExpr(org.mapleir.ir.code.expr.VarExpr) Expr(org.mapleir.ir.code.Expr) AbstractCopyStmt(org.mapleir.ir.code.stmt.copy.AbstractCopyStmt) VarExpr(org.mapleir.ir.code.expr.VarExpr) HashSet(java.util.HashSet)

Example 34 with VarExpr

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;
}
Also used : FlowEdge(org.mapleir.flowgraph.edges.FlowEdge) InvocationExpr(org.mapleir.ir.code.expr.invoke.InvocationExpr) VarExpr(org.mapleir.ir.code.expr.VarExpr) Expr(org.mapleir.ir.code.Expr) BasicBlock(org.mapleir.ir.cfg.BasicBlock) Local(org.mapleir.ir.locals.Local) VarExpr(org.mapleir.ir.code.expr.VarExpr) InvocationExpr(org.mapleir.ir.code.expr.invoke.InvocationExpr) Stmt(org.mapleir.ir.code.Stmt)

Example 35 with VarExpr

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);
}
Also used : ConstantExpr(org.mapleir.ir.code.expr.ConstantExpr) Local(org.mapleir.ir.locals.Local) Type(org.objectweb.asm.Type) ArithmeticExpr(org.mapleir.ir.code.expr.ArithmeticExpr) VarExpr(org.mapleir.ir.code.expr.VarExpr) Expr(org.mapleir.ir.code.Expr) ConstantExpr(org.mapleir.ir.code.expr.ConstantExpr) CastExpr(org.mapleir.ir.code.expr.CastExpr) ComparisonExpr(org.mapleir.ir.code.expr.ComparisonExpr) NegationExpr(org.mapleir.ir.code.expr.NegationExpr) ArithmeticExpr(org.mapleir.ir.code.expr.ArithmeticExpr) ControlFlowGraph(org.mapleir.ir.cfg.ControlFlowGraph) Iterator(java.util.Iterator) CastExpr(org.mapleir.ir.code.expr.CastExpr) VarExpr(org.mapleir.ir.code.expr.VarExpr) TaintableSet(org.mapleir.stdlib.collections.taint.TaintableSet) Pair(javafx.util.Pair) NegationExpr(org.mapleir.ir.code.expr.NegationExpr)

Aggregations

VarExpr (org.mapleir.ir.code.expr.VarExpr)51 Expr (org.mapleir.ir.code.Expr)37 Local (org.mapleir.ir.locals.Local)32 PhiExpr (org.mapleir.ir.code.expr.PhiExpr)31 AbstractCopyStmt (org.mapleir.ir.code.stmt.copy.AbstractCopyStmt)30 VersionedLocal (org.mapleir.ir.locals.impl.VersionedLocal)29 BasicBlock (org.mapleir.ir.cfg.BasicBlock)26 Stmt (org.mapleir.ir.code.Stmt)25 CopyPhiStmt (org.mapleir.ir.code.stmt.copy.CopyPhiStmt)25 CopyVarStmt (org.mapleir.ir.code.stmt.copy.CopyVarStmt)21 ConstantExpr (org.mapleir.ir.code.expr.ConstantExpr)15 InvocationExpr (org.mapleir.ir.code.expr.invoke.InvocationExpr)13 InitialisedObjectExpr (org.mapleir.ir.code.expr.invoke.InitialisedObjectExpr)12 BasicLocal (org.mapleir.ir.locals.impl.BasicLocal)7 NullPermeableHashMap (org.mapleir.stdlib.collections.map.NullPermeableHashMap)7 Type (org.objectweb.asm.Type)7 HashSet (java.util.HashSet)6 Constraint (org.mapleir.ir.cfg.builder.ssaopt.Constraint)6 ConditionalJumpStmt (org.mapleir.ir.code.stmt.ConditionalJumpStmt)5 PopStmt (org.mapleir.ir.code.stmt.PopStmt)5