Search in sources :

Example 36 with BasicBlock

use of org.mapleir.ir.cfg.BasicBlock 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 37 with BasicBlock

use of org.mapleir.ir.cfg.BasicBlock in project maple-ir by LLVM-but-worse.

the class LiftConstructorCallsPass method split.

private void split(ControlFlowGraph cfg, BasicBlock b, Stmt at) {
    BasicBlock newBlock = new BasicBlock(cfg, cfg.vertices().size() + 1, new LabelNode());
    cfg.addVertex(newBlock);
    System.out.println(ControlFlowGraph.printBlock(b));
    System.out.println("  to " + at);
    int index = b.indexOf(at) + 1;
    int size = b.size();
    for (int i = index; i < size; i++) {
        Stmt stmt = b.remove(index);
        stmt.setBlock(newBlock);
        newBlock.add(stmt);
    }
}
Also used : LabelNode(org.objectweb.asm.tree.LabelNode) BasicBlock(org.mapleir.ir.cfg.BasicBlock) Stmt(org.mapleir.ir.code.Stmt)

Example 38 with BasicBlock

use of org.mapleir.ir.cfg.BasicBlock 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 39 with BasicBlock

use of org.mapleir.ir.cfg.BasicBlock in project maple-ir by LLVM-but-worse.

the class IPAnalysis method visitMethod.

@Override
protected void visitMethod(MethodNode m) {
    // Callbacks
    for (IPAnalysisVisitor v : visitors) {
        v.preVisitMethod(this, m);
    }
    // Do not trace library calls
    if (context.getApplication().isLibraryClass(m.owner.name)) {
        return;
    }
    // Create a mapping between the actual variable table indices and the parameter
    // indices in the method descriptor.
    boolean isStatic = (m.access & Opcodes.ACC_STATIC) != 0;
    int paramCount = Type.getArgumentTypes(m.desc).length;
    int off = (isStatic ? 0 : 1);
    int synthCount = paramCount + off;
    List<List<Expr>> lists = new ArrayList<>(synthCount);
    int[] idxs = new int[synthCount];
    // Scan for synthetic copies to populate indices
    ControlFlowGraph cfg = context.getIRCache().getFor(m);
    BasicBlock entry = cfg.getEntries().iterator().next();
    /* static:
		 *  first arg = 0
		 *
		 * non-static:
		 *  this = 0
		 *  first arg = 1*/
    int paramIndex = 0;
    for (Stmt stmt : entry) {
        if (stmt.getOpcode() == LOCAL_STORE) {
            CopyVarStmt cvs = (CopyVarStmt) stmt;
            if (cvs.isSynthetic()) {
                int varIndex = cvs.getVariable().getLocal().getIndex();
                if (!isStatic && varIndex == 0)
                    continue;
                idxs[paramIndex++] = varIndex;
                continue;
            }
        }
        break;
    }
    for (int j = 0; j < paramCount; j++) {
        lists.add(new ArrayList<>());
    }
    paramIndices.put(m, idxs);
    parameterInputs.put(m, lists);
    callers.put(m, new HashSet<>());
    // Callbacks
    for (IPAnalysisVisitor v : visitors) {
        v.postVisitMethod(this, m);
    }
}
Also used : CopyVarStmt(org.mapleir.ir.code.stmt.copy.CopyVarStmt) ArrayList(java.util.ArrayList) BasicBlock(org.mapleir.ir.cfg.BasicBlock) Stmt(org.mapleir.ir.code.Stmt) CopyVarStmt(org.mapleir.ir.code.stmt.copy.CopyVarStmt) ControlFlowGraph(org.mapleir.ir.cfg.ControlFlowGraph) ArrayList(java.util.ArrayList) List(java.util.List)

Example 40 with BasicBlock

use of org.mapleir.ir.cfg.BasicBlock in project maple-ir by LLVM-but-worse.

the class MethodRenamerPass method rename.

public static void rename(AnalysisContext cxt, Map<MethodNode, String> remapped, boolean warn) {
    ApplicationClassSource source = cxt.getApplication();
    InvocationResolver resolver = cxt.getInvocationResolver();
    for (ClassNode cn : source.iterate()) {
        {
            if (cn.outerMethod != null) {
                // ClassNode owner = tree.getClass(cn.outerClass);
                System.out.println("Outer: " + cn.outerClass + "." + cn.outerMethod + " " + cn.outerMethodDesc);
                cn.outerClass = null;
                cn.outerMethod = null;
                cn.outerMethodDesc = null;
            // System.out.println(owner.name);
            // do {
            // for(MethodNode m : owner.methods) {
            // System.out.println(m);
            // if(m.name.equals(cn.outerMethod) && m.desc.equals(cn.outerMethodDesc)) {
            // System.out.println("m: " + m);
            // }
            // }
            // owner = tree.getClass(owner.superName);
            // System.out.println(cn.superName);
            // System.out.println(owner);
            // } while(owner != null);
            }
        }
        Set<Expr> visited = new HashSet<>();
        for (MethodNode m : cn.methods) {
            ControlFlowGraph cfg = cxt.getIRCache().getFor(m);
            for (BasicBlock b : cfg.vertices()) {
                for (Stmt stmt : b) {
                    for (Expr e : stmt.enumerateOnlyChildren()) {
                        if (e.getOpcode() == Opcode.INVOKE) {
                            InvocationExpr invoke = (InvocationExpr) e;
                            if (visited.contains(invoke)) {
                                throw new RuntimeException(invoke.toString());
                            }
                            visited.add(invoke);
                            if (invoke.getOwner().startsWith("[")) {
                                System.err.println("  ignore array object invoke: " + invoke + ", owner: " + invoke.getOwner());
                                continue;
                            }
                            if (invoke.isStatic()) {
                                MethodNode site = resolver.resolveStaticCall(invoke.getOwner(), invoke.getName(), invoke.getDesc());
                                if (site != null) {
                                    if (remapped.containsKey(site)) {
                                        invoke.setName(remapped.get(site));
                                    } else {
                                        if (warn && mustMark(source, invoke.getOwner())) {
                                            System.err.println("  invalid site(s): " + invoke);
                                        }
                                    }
                                } else {
                                    if (mustMark(source, invoke.getOwner())) {
                                        System.err.printf("  can't resolve(s) %s ; %s.%s %s%n", invoke, invoke.getOwner(), invoke.getName(), invoke.getDesc());
                                        if (invoke.getOwner().equals("hey")) {
                                            for (MethodNode mm : cxt.getApplication().findClassNode(invoke.getOwner()).methods) {
                                                System.out.println(mm);
                                            }
                                            throw new UnsupportedOperationException();
                                        }
                                    }
                                }
                            } else {
                                // Set<MethodNode> sites = resolver.resolveVirtualCalls(invoke.getOwner(), invoke.getName(), invoke.getDesc());
                                // Set<ClassNode> classes = source.getStructures().dfsTree(cn, true, true, true);
                                // Set<MethodNode> sites = getVirtualMethods(cxt, classes, invoke.getName(), invoke.getDesc());
                                Set<MethodNode> sites = resolver.getHierarchyMethodChain(source.findClassNode(invoke.getOwner()), invoke.getName(), invoke.getDesc(), true);
                                if (sites.size() > 0) {
                                    /* all of the sites must be linked by the same name,
										 * so we can use any to find the new name. */
                                    boolean anyContains = false;
                                    boolean allContains = true;
                                    for (MethodNode s : sites) {
                                        anyContains |= remapped.containsKey(s);
                                        allContains &= remapped.containsKey(s);
                                    }
                                    if (anyContains && !allContains) {
                                        System.err.println("mismatch: ");
                                        // System.err.println(classes);
                                        System.err.println(sites);
                                        throw new RuntimeException();
                                    }
                                    MethodNode site = sites.iterator().next();
                                    if (remapped.containsKey(site)) {
                                        invoke.setName(remapped.get(site));
                                    } else {
                                        if (warn && !site.name.equals("<init>") && canRename(cxt, sites)) {
                                            System.err.println("  invalid site(v): " + invoke + ", " + sites);
                                        }
                                    }
                                } else {
                                    if (mustMark(source, invoke.getOwner())) {
                                        System.err.println("  can't resolve(v) " + invoke + ", owner: " + invoke.getOwner() + " desc " + invoke.getDesc());
                                    // System.err.println("  classes: " + classes);
                                    }
                                }
                            }
                        } else if (e.getOpcode() == Opcode.DYNAMIC_INVOKE) {
                            throw new UnsupportedOperationException();
                        }
                    }
                }
            }
        }
    }
    /* Rename the methods after as we need to resolve
		 * them using the old names during the invocation 
		 * analysis above. */
    for (Entry<MethodNode, String> e : remapped.entrySet()) {
        // System.out.printf("%s -> %s%n", e.getKey(), e.getValue());
        e.getKey().name = e.getValue();
    }
}
Also used : ClassNode(org.objectweb.asm.tree.ClassNode) BasicBlock(org.mapleir.ir.cfg.BasicBlock) Stmt(org.mapleir.ir.code.Stmt) ApplicationClassSource(org.mapleir.app.service.ApplicationClassSource) InvocationExpr(org.mapleir.ir.code.expr.invoke.InvocationExpr) Expr(org.mapleir.ir.code.Expr) MethodNode(org.objectweb.asm.tree.MethodNode) ControlFlowGraph(org.mapleir.ir.cfg.ControlFlowGraph) InvocationResolver(org.mapleir.app.service.InvocationResolver) InvocationExpr(org.mapleir.ir.code.expr.invoke.InvocationExpr) HashSet(java.util.HashSet)

Aggregations

BasicBlock (org.mapleir.ir.cfg.BasicBlock)70 Stmt (org.mapleir.ir.code.Stmt)37 Expr (org.mapleir.ir.code.Expr)34 Local (org.mapleir.ir.locals.Local)30 VarExpr (org.mapleir.ir.code.expr.VarExpr)29 CopyPhiStmt (org.mapleir.ir.code.stmt.copy.CopyPhiStmt)25 AbstractCopyStmt (org.mapleir.ir.code.stmt.copy.AbstractCopyStmt)24 CopyVarStmt (org.mapleir.ir.code.stmt.copy.CopyVarStmt)22 PhiExpr (org.mapleir.ir.code.expr.PhiExpr)19 VersionedLocal (org.mapleir.ir.locals.impl.VersionedLocal)19 HashSet (java.util.HashSet)12 ControlFlowGraph (org.mapleir.ir.cfg.ControlFlowGraph)11 UnconditionalJumpStmt (org.mapleir.ir.code.stmt.UnconditionalJumpStmt)10 InvocationExpr (org.mapleir.ir.code.expr.invoke.InvocationExpr)9 BasicLocal (org.mapleir.ir.locals.impl.BasicLocal)9 NullPermeableHashMap (org.mapleir.stdlib.collections.map.NullPermeableHashMap)9 ConditionalJumpStmt (org.mapleir.ir.code.stmt.ConditionalJumpStmt)8 Type (org.objectweb.asm.Type)7 ArrayList (java.util.ArrayList)6 ConstantExpr (org.mapleir.ir.code.expr.ConstantExpr)6