Search in sources :

Example 46 with Expr

use of org.mapleir.ir.code.Expr in project maple-ir by LLVM-but-worse.

the class SSAGenPass method resolveShadowedLocals.

private void resolveShadowedLocals() {
    Set<VersionedLocal> visited = new HashSet<>();
    for (Entry<VersionedLocal, Set<VersionedLocal>> e : shadowed.entrySet()) {
        if (!visited.contains(e.getKey())) {
            Set<VersionedLocal> set = e.getValue();
            visited.addAll(set);
            Set<VersionedLocal> lvars = new HashSet<>();
            for (VersionedLocal l : set) {
                if (!l.isStack()) {
                    lvars.add(l);
                }
            }
            /* find a suitable spill variable:
				 *  favour lvars
				 *  favour lowest version */
            VersionedLocal spill;
            if (lvars.isEmpty()) {
                /* all vars are svars. */
                spill = findLowest(set);
            } else if (lvars.size() == 1) {
                spill = lvars.iterator().next();
            } else {
                /* multiple lvars. // TODO: tweak? */
                // System.err.println(e.getKey() + "    " + lvars);
                spill = findLowest(lvars);
            }
            // System.out.println(set + "  spill; " + spill);
            /* now that we've chosen a spill var, we
				 * find the original copy, i.e. the one
				 * which has a runtime computed value
				 * as it's rhs. we then replace the
				 * target of that copy to the spill
				 * var and remove the definitions of the
				 * shadowed vars. we then rename all
				 * uses of the shadowed vars with the
				 * spill. */
            Set<AbstractCopyStmt> orig = new HashSet<>();
            Set<VarExpr> spillUses = pool.uses.get(spill);
            // System.out.println(set);
            for (VersionedLocal vl : set) {
                AbstractCopyStmt copy = pool.defs.get(vl);
                // System.out.println(vl);
                Expr ex = copy.getExpression();
                if (vl != spill) {
                    if (ex.getOpcode() != Opcode.LOCAL_LOAD) {
                        orig.add(copy);
                    } else {
                        // System.out.println("del1: " + copy);
                        removeSimpleCopy(copy);
                    }
                    /* transfer the uses of each shadowed
						 * var to the spill var, since we
						 * rename all of the shadowed vars. */
                    Set<VarExpr> useSet = pool.uses.get(vl);
                    // System.out.println("uses of " + vl + " ; " + useSet);
                    for (VarExpr v : useSet) {
                        v.setLocal(spill);
                    }
                    spillUses.addAll(useSet);
                    useSet.clear();
                    pool.uses.remove(vl);
                } else {
                    // System.out.println("del2: " + copy);
                    removeSimpleCopy(copy);
                }
                pool.defs.remove(vl);
            }
            if (orig.size() != 1) {
                throw new UnsupportedOperationException(String.format("set:%s, spill:%s, orig:%s", set, spill, orig));
            }
            AbstractCopyStmt copy = orig.iterator().next();
            copy.getVariable().setLocal(spill);
            pool.defs.put(spill, copy);
        }
    }
}
Also used : VersionedLocal(org.mapleir.ir.locals.impl.VersionedLocal) ConstantExpr(org.mapleir.ir.code.expr.ConstantExpr) InitialisedObjectExpr(org.mapleir.ir.code.expr.invoke.InitialisedObjectExpr) InvocationExpr(org.mapleir.ir.code.expr.invoke.InvocationExpr) 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) VarExpr(org.mapleir.ir.code.expr.VarExpr)

Example 47 with Expr

use of org.mapleir.ir.code.Expr in project maple-ir by LLVM-but-worse.

the class DumbExceptionAnalysis method getPossibleUserThrowables.

@Override
public Set<Type> getPossibleUserThrowables(CodeUnit u) {
    Set<Type> set = new HashSet<>();
    if (u.isFlagSet(CodeUnit.FLAG_STMT)) {
        Stmt s = (Stmt) u;
        canThrowStmt(s, set);
        for (Expr e : s.enumerateOnlyChildren()) {
            canThrowExpr(e, set);
        }
    } else {
        for (Expr e : ((Expr) u).enumerateWithSelf()) {
            canThrowExpr(e, set);
        }
    }
    return set;
}
Also used : Type(org.objectweb.asm.Type) ArithmeticExpr(org.mapleir.ir.code.expr.ArithmeticExpr) Expr(org.mapleir.ir.code.Expr) ConstantExpr(org.mapleir.ir.code.expr.ConstantExpr) HashSet(java.util.HashSet) ThrowStmt(org.mapleir.ir.code.stmt.ThrowStmt) MonitorStmt(org.mapleir.ir.code.stmt.MonitorStmt) Stmt(org.mapleir.ir.code.Stmt)

Example 48 with Expr

use of org.mapleir.ir.code.Expr in project maple-ir by LLVM-but-worse.

the class ExpressionEvaluator method eval.

public ConstantExpr eval(LocalsPool pool, Expr e) {
    if (e.getOpcode() == CONST_LOAD) {
        return ((ConstantExpr) e).copy();
    } else if (e.getOpcode() == ARITHMETIC) {
        ArithmeticExpr ae = (ArithmeticExpr) e;
        Expr l = ae.getLeft();
        Expr r = ae.getRight();
        Expr le = eval(pool, l);
        Expr re = eval(pool, r);
        if (le != null && re != null) {
            ConstantExpr lc = (ConstantExpr) le;
            ConstantExpr rc = (ConstantExpr) re;
            EvaluationFunctor<Number> b = factory.arithmetic(lc.getType(), rc.getType(), ae.getType(), ae.getOperator());
            return new ConstantExpr(b.eval(lc.getConstant(), rc.getConstant()));
        }
    } else if (e.getOpcode() == NEGATE) {
        NegationExpr neg = (NegationExpr) e;
        Expr e2 = eval(pool, neg.getExpression());
        if (e2 != null) {
            ConstantExpr ce = (ConstantExpr) e2;
            EvaluationFunctor<Number> b = factory.negate(e2.getType());
            return new ConstantExpr(b.eval(ce.getConstant()));
        }
    } else if (e.getOpcode() == LOCAL_LOAD) {
        VarExpr v = (VarExpr) e;
        Local l = v.getLocal();
        AbstractCopyStmt def = pool.defs.get(l);
        Expr rhs = def.getExpression();
        if (rhs.getOpcode() == LOCAL_LOAD) {
            VarExpr v2 = (VarExpr) rhs;
            // synthetic copies lhs = rhs;
            if (v2.getLocal() == l) {
                return null;
            }
        }
        return eval(pool, rhs);
    } else if (e.getOpcode() == CAST) {
        CastExpr cast = (CastExpr) e;
        Expr e2 = eval(pool, cast.getExpression());
        if (e2 != null) {
            ConstantExpr ce = (ConstantExpr) e2;
            if (!ce.getType().equals(cast.getExpression().getType())) {
                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) {
                return null;
            }
            EvaluationFunctor<Number> b = factory.cast(from, to);
            return new ConstantExpr(b.eval(ce.getConstant()), to);
        }
    } else if (e.getOpcode() == COMPARE) {
        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;
            EvaluationFunctor<Number> b = factory.compare(lc.getType(), rc.getType(), comp.getComparisonType());
            return new ConstantExpr(b.eval(lc.getConstant(), rc.getConstant()), Type.INT_TYPE);
        }
    }
    return null;
}
Also used : ComparisonExpr(org.mapleir.ir.code.expr.ComparisonExpr) 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) CastExpr(org.mapleir.ir.code.expr.CastExpr) VarExpr(org.mapleir.ir.code.expr.VarExpr) AbstractCopyStmt(org.mapleir.ir.code.stmt.copy.AbstractCopyStmt) NegationExpr(org.mapleir.ir.code.expr.NegationExpr)

Example 49 with Expr

use of org.mapleir.ir.code.Expr in project maple-ir by LLVM-but-worse.

the class ExpressionEvaluator method reassociate.

private ArithmeticExpr reassociate(LocalsPool pool, ArithmeticExpr ae) {
    ArithmeticExpr leftAe = (ArithmeticExpr) ae.getLeft();
    Operator operatorA = leftAe.getOperator();
    Operator operatorB = ae.getOperator();
    Expr r1 = eval(pool, leftAe.getRight());
    Expr r2 = eval(pool, ae.getRight());
    if (r1 != null && r2 != null) {
        ConstantExpr cr1 = (ConstantExpr) r1;
        ConstantExpr cr2 = (ConstantExpr) r2;
        int sign = 0;
        if ((operatorA == MUL && operatorB == MUL)) {
            sign = 1;
        } else if (operatorA == ADD && (operatorB == ADD || operatorB == SUB)) {
            // what about overflow?? integers mod 2^32 forms a group over addition...should be ok?
            sign = 1;
        } else if (operatorA == SUB && (operatorB == ADD || operatorB == SUB)) {
            sign = -1;
        }
        if (sign != 0) {
            ConstantExpr cr1r2 = eval(pool, new ArithmeticExpr(sign > 0 ? cr2 : new NegationExpr(cr2), cr1, operatorB));
            Object associated = cr1r2.getConstant();
            return new ArithmeticExpr(new ConstantExpr(associated, cr1r2.getType()), leftAe.getLeft().copy(), operatorA);
        }
    }
    return null;
}
Also used : Operator(org.mapleir.ir.code.expr.ArithmeticExpr.Operator) 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) ConstantExpr(org.mapleir.ir.code.expr.ConstantExpr) NegationExpr(org.mapleir.ir.code.expr.NegationExpr)

Example 50 with Expr

use of org.mapleir.ir.code.Expr in project maple-ir by LLVM-but-worse.

the class ExpressionEvaluator method simplifyMultiplication.

private Expr simplifyMultiplication(LocalsPool pool, ArithmeticExpr e) {
    if (e.getOperator() != Operator.MUL)
        throw new IllegalArgumentException("Only works on multiplication exprs");
    Expr r = e.getRight();
    ConstantExpr re = eval(pool, r);
    if (re != null) {
        Object o = re.getConstant();
        if (o instanceof Integer || o instanceof Long) {
            if (FieldRSADecryptionPass.__eq((Number) o, 1, o instanceof Long)) {
                return e.getLeft().copy();
            } else if (FieldRSADecryptionPass.__eq((Number) o, 0, o instanceof Long)) {
                return new ConstantExpr(0, re.getType());
            }
        }
    }
    return null;
}
Also used : 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) ConstantExpr(org.mapleir.ir.code.expr.ConstantExpr)

Aggregations

Expr (org.mapleir.ir.code.Expr)87 VarExpr (org.mapleir.ir.code.expr.VarExpr)46 InvocationExpr (org.mapleir.ir.code.expr.invoke.InvocationExpr)45 BasicBlock (org.mapleir.ir.cfg.BasicBlock)32 PhiExpr (org.mapleir.ir.code.expr.PhiExpr)31 Stmt (org.mapleir.ir.code.Stmt)29 ConstantExpr (org.mapleir.ir.code.expr.ConstantExpr)26 AbstractCopyStmt (org.mapleir.ir.code.stmt.copy.AbstractCopyStmt)26 Local (org.mapleir.ir.locals.Local)22 Type (org.objectweb.asm.Type)21 VersionedLocal (org.mapleir.ir.locals.impl.VersionedLocal)20 CopyPhiStmt (org.mapleir.ir.code.stmt.copy.CopyPhiStmt)19 InitialisedObjectExpr (org.mapleir.ir.code.expr.invoke.InitialisedObjectExpr)17 ComparisonType (org.mapleir.ir.code.stmt.ConditionalJumpStmt.ComparisonType)14 CopyVarStmt (org.mapleir.ir.code.stmt.copy.CopyVarStmt)14 ValueComparisonType (org.mapleir.ir.code.expr.ComparisonExpr.ValueComparisonType)13 ArrayType (org.mapleir.ir.TypeUtils.ArrayType)12 HashSet (java.util.HashSet)11 ArithmeticExpr (org.mapleir.ir.code.expr.ArithmeticExpr)11 ControlFlowGraph (org.mapleir.ir.cfg.ControlFlowGraph)9