Search in sources :

Example 26 with LabelStmt

use of com.googlecode.dex2jar.ir.stmt.LabelStmt in project dex2jar by pxb1988.

the class FillArrayTransformer method searchForArrayObject.

private Map<Local, ArrayObject> searchForArrayObject(IrMethod method) {
    final Map<Local, ArrayObject> arraySizes = new HashMap<>();
    if (method.locals.size() == 0) {
        return arraySizes;
    }
    Cfg.createCFG(method);
    Cfg.dfsVisit(method, new Cfg.DfsVisitor() {

        @Override
        public void onVisit(Stmt p) {
            if (p.st == Stmt.ST.ASSIGN) {
                if (p.getOp2().vt == Value.VT.NEW_ARRAY && p.getOp1().vt == Value.VT.LOCAL) {
                    TypeExpr ae = (TypeExpr) p.getOp2();
                    if (ae.getOp().vt == Value.VT.CONSTANT) {
                        int size = ((Number) ((Constant) ae.getOp()).value).intValue();
                        // }
                        if (size >= 0) {
                            arraySizes.put((Local) p.getOp1(), new ArrayObject(size, ae.type, (AssignStmt) p));
                        }
                    }
                } else if (p.getOp1().vt == Value.VT.ARRAY) {
                    ArrayExpr ae = (ArrayExpr) p.getOp1();
                    if (ae.getOp1().vt == Value.VT.LOCAL) {
                        Local local = (Local) ae.getOp1();
                        ArrayObject arrayObject = arraySizes.get(local);
                        if (arrayObject != null) {
                            if (ae.getOp2().vt == Value.VT.CONSTANT) {
                                arrayObject.putItem.add(p);
                            } else {
                                arraySizes.remove(local);
                            }
                        }
                    }
                }
            } else if (p.st == Stmt.ST.FILL_ARRAY_DATA) {
                if (p.getOp1().vt == Value.VT.LOCAL) {
                    Local local = (Local) p.getOp1();
                    ArrayObject arrayObject = arraySizes.get(local);
                    if (arrayObject != null) {
                        arrayObject.putItem.add(p);
                    }
                }
            }
        }
    });
    if (arraySizes.size() > 0) {
        Set<Local> set = new HashSet<Local>();
        if (method.phiLabels != null) {
            for (LabelStmt labelStmt : method.phiLabels) {
                if (labelStmt.phis != null) {
                    for (AssignStmt as : labelStmt.phis) {
                        set.add((Local) as.getOp1());
                        for (Value v : as.getOp2().getOps()) {
                            set.add((Local) v);
                        }
                    }
                }
            }
        }
        if (set.size() > 0) {
            for (Local local : set) {
                arraySizes.remove(local);
            }
        }
    }
    return arraySizes;
}
Also used : LabelStmt(com.googlecode.dex2jar.ir.stmt.LabelStmt) Cfg(com.googlecode.dex2jar.ir.ts.Cfg) AssignStmt(com.googlecode.dex2jar.ir.stmt.AssignStmt) LabelStmt(com.googlecode.dex2jar.ir.stmt.LabelStmt) AssignStmt(com.googlecode.dex2jar.ir.stmt.AssignStmt) Stmt(com.googlecode.dex2jar.ir.stmt.Stmt)

Example 27 with LabelStmt

use of com.googlecode.dex2jar.ir.stmt.LabelStmt in project dex2jar by pxb1988.

the class UnSSATransformer method transform.

@Override
public void transform(IrMethod method) {
    if (method.phiLabels == null || method.phiLabels.size() == 0) {
        return;
    }
    // 1. Live analyze the method,
    // a. remove Phi,
    // b. record parameter reference
    LiveA liveA = new LiveA(method);
    liveA.analyze();
    genRegGraph(method, liveA);
    // 2. insert x=y
    fixPhi(method, method.phiLabels);
    insertAssignPath(method, method.phiLabels);
    // 4. clean up
    for (Local local : method.locals) {
        local.tag = null;
    }
    for (Stmt stmt : method.stmts) {
        stmt.frame = null;
    }
    for (LabelStmt labelStmt : method.phiLabels) {
        labelStmt.phis = null;
    }
    method.phiLabels = null;
}
Also used : LabelStmt(com.googlecode.dex2jar.ir.stmt.LabelStmt) Local(com.googlecode.dex2jar.ir.expr.Local) LabelStmt(com.googlecode.dex2jar.ir.stmt.LabelStmt) JumpStmt(com.googlecode.dex2jar.ir.stmt.JumpStmt) AssignStmt(com.googlecode.dex2jar.ir.stmt.AssignStmt) Stmt(com.googlecode.dex2jar.ir.stmt.Stmt)

Example 28 with LabelStmt

use of com.googlecode.dex2jar.ir.stmt.LabelStmt in project dex2jar by pxb1988.

the class UnSSATransformer method fixPhi.

/**
     * there is somewhere both a and its possible x is both live, insert a=x, will change the meaning for example
     * 
     * <pre>
     *                      L0:
     *                      a = phi(b, ... )
     *                      b = 234;
     *                      if a>0 goto L0: // a, b both live here
     *                      ...
     * </pre>
     * 
     * after insert a=b before the if stmt, the programe change to
     * 
     * <pre>
     *                      L0:
     *                      // a = phi(b, ... )
     *                      b = 234;
     *                      a = b
     *                      if a>0 goto L0:
     *                      ...
     * </pre>
     * 
     * the solution is by introduce a new local x
     * 
     * <pre>
     *                      L0:
     *                      x = phi(b, ... )
     *                      a = x
     *                      b = 234;
     *                      if a>0 goto L0: // a, b both live here
     *                      ...
     * </pre>
     * 
     * insert x = b is ok now
     * 
     * <pre>
     *                      L0:
     *                      // x = phi(b, ... )
     *                      a = x
     *                      b = 234;
     *                      x = b
     *                      if a>0 goto L0: // a, b both live here
     *                      ...
     * </pre>
     * 
     * @param phiLabels
     */
private void fixPhi(IrMethod method, Collection<LabelStmt> phiLabels) {
    for (LabelStmt labelStmt : phiLabels) {
        List<AssignStmt> phis = (List<AssignStmt>) labelStmt.phis;
        for (AssignStmt phi : phis) {
            Local a = (Local) phi.getOp1();
            PhiExpr b = (PhiExpr) phi.getOp2();
            boolean introduceNewLocal = false;
            RegAssign aReg = (RegAssign) a.tag;
            for (Value op : b.getOps()) {
                RegAssign bReg = (RegAssign) ((Local) op).tag;
                if (aReg.excludes.contains(bReg)) {
                    introduceNewLocal = true;
                    break;
                }
            }
            if (introduceNewLocal) {
                Local newLocal = (Local) a.clone();
                if (DEBUG) {
                    newLocal.debugName = "x" + method.locals.size();
                }
                phi.op1 = newLocal;
                RegAssign newRegAssign = new RegAssign();
                newLocal.tag = newRegAssign;
                method.locals.add(newLocal);
                Stmt newAssigStmt = Stmts.nAssign(a, newLocal);
                Stmt next = labelStmt.getNext();
                if (next != null && next.st == ST.IDENTITY && next.getOp2().vt == VT.EXCEPTION_REF) {
                    // it's a handler, insert after the exception ref
                    method.stmts.insertAfter(next, newAssigStmt);
                } else {
                    method.stmts.insertAfter(labelStmt, newAssigStmt);
                }
                LiveV[] frame = (LiveV[]) labelStmt.frame;
                if (DEBUG) {
                    LiveV[] copy = frame.clone();
                    LiveV n = new LiveV();
                    n.local = a;
                    n.used = true;
                    copy[a._ls_index] = new LiveV();
                    newAssigStmt.frame = copy;
                }
                LiveV thePhi = frame[a._ls_index];
                thePhi.local = newLocal;
                for (LiveV v : frame) {
                    if (v != null && v.used) {
                        RegAssign s = (RegAssign) v.local.tag;
                        s.excludes.add(newRegAssign);
                        newRegAssign.excludes.add(s);
                    }
                }
            }
        }
    }
}
Also used : LabelStmt(com.googlecode.dex2jar.ir.stmt.LabelStmt) PhiExpr(com.googlecode.dex2jar.ir.expr.PhiExpr) AssignStmt(com.googlecode.dex2jar.ir.stmt.AssignStmt) Value(com.googlecode.dex2jar.ir.expr.Value) AnalyzeValue(com.googlecode.dex2jar.ir.ts.an.AnalyzeValue) Local(com.googlecode.dex2jar.ir.expr.Local) StmtList(com.googlecode.dex2jar.ir.stmt.StmtList) ArrayList(java.util.ArrayList) List(java.util.List) LabelStmt(com.googlecode.dex2jar.ir.stmt.LabelStmt) JumpStmt(com.googlecode.dex2jar.ir.stmt.JumpStmt) AssignStmt(com.googlecode.dex2jar.ir.stmt.AssignStmt) Stmt(com.googlecode.dex2jar.ir.stmt.Stmt)

Example 29 with LabelStmt

use of com.googlecode.dex2jar.ir.stmt.LabelStmt in project dex2jar by pxb1988.

the class UnSSATransformer method genRegGraph.

private void genRegGraph(IrMethod method, LiveA liveA) {
    for (Local local : method.locals) {
        local.tag = new RegAssign();
    }
    Set<Stmt> tos = new HashSet<>();
    for (Stmt stmt : method.stmts) {
        if ((stmt.st == ST.ASSIGN || stmt.st == ST.IDENTITY) && stmt.getOp1().vt == VT.LOCAL) {
            Local localAssignTo = (Local) stmt.getOp1();
            RegAssign regAssignTo = (RegAssign) localAssignTo.tag;
            Set<Integer> excludeIdx = new HashSet<>();
            Cfg.collectTos(stmt, tos);
            for (Stmt target : tos) {
                LiveV[] frame = (LiveV[]) target.frame;
                if (frame == null) {
                    continue;
                }
                // exclude thisReg and phiReg
                excludeIdx.clear();
                excludeIdx.add(localAssignTo._ls_index);
                if (target.st == ST.LABEL) {
                    LabelStmt label = (LabelStmt) target;
                    if (label.phis != null) {
                        for (AssignStmt phiAssignStmt : (List<AssignStmt>) label.phis) {
                            Local phiLocal = (Local) phiAssignStmt.getOp1();
                            excludeIdx.add(phiLocal._ls_index);
                        }
                    }
                }
                for (int i = 0; i < frame.length; i++) {
                    if (excludeIdx.contains(i)) {
                        continue;
                    }
                    LiveV v = frame[i];
                    if (v != null && v.used) {
                        RegAssign b = (RegAssign) v.local.tag;
                        regAssignTo.excludes.add(b);
                        b.excludes.add(regAssignTo);
                    }
                }
            }
            tos.clear();
        } else if (stmt.st == ST.LABEL) {
            //
            LabelStmt label = (LabelStmt) stmt;
            if (label.phis != null) {
                for (AssignStmt phiAssignStmt : (List<AssignStmt>) label.phis) {
                    Local phiLocal = (Local) phiAssignStmt.getOp1();
                    RegAssign a = (RegAssign) phiLocal.tag;
                    LiveV[] frame = (LiveV[]) stmt.frame;
                    for (LiveV v : frame) {
                        if (v != null && v.used) {
                            RegAssign b = (RegAssign) v.local.tag;
                            a.excludes.add(b);
                            b.excludes.add(a);
                        }
                    }
                }
            }
        }
    }
    if (DEBUG) {
        System.out.println(liveA.toString());
    }
}
Also used : LabelStmt(com.googlecode.dex2jar.ir.stmt.LabelStmt) AssignStmt(com.googlecode.dex2jar.ir.stmt.AssignStmt) Local(com.googlecode.dex2jar.ir.expr.Local) LabelStmt(com.googlecode.dex2jar.ir.stmt.LabelStmt) JumpStmt(com.googlecode.dex2jar.ir.stmt.JumpStmt) AssignStmt(com.googlecode.dex2jar.ir.stmt.AssignStmt) Stmt(com.googlecode.dex2jar.ir.stmt.Stmt) StmtList(com.googlecode.dex2jar.ir.stmt.StmtList) ArrayList(java.util.ArrayList) List(java.util.List) HashSet(java.util.HashSet)

Example 30 with LabelStmt

use of com.googlecode.dex2jar.ir.stmt.LabelStmt in project dex2jar by pxb1988.

the class BaseAnalyze method init.

protected void init() {
    if (reindexLocal) {
        int index = 0;
        for (Local local : method.locals) {
            local._ls_index = index;
            index++;
        }
    }
    if (DEBUG) {
        int idx = 0;
        for (Stmt s : method.stmts) {
            if (s.st == Stmt.ST.LABEL) {
                LabelStmt label = (LabelStmt) s;
                label.displayName = "L" + idx++;
            }
        }
    }
    initCFG();
}
Also used : LabelStmt(com.googlecode.dex2jar.ir.stmt.LabelStmt) Local(com.googlecode.dex2jar.ir.expr.Local) LabelStmt(com.googlecode.dex2jar.ir.stmt.LabelStmt) AssignStmt(com.googlecode.dex2jar.ir.stmt.AssignStmt) Stmt(com.googlecode.dex2jar.ir.stmt.Stmt)

Aggregations

LabelStmt (com.googlecode.dex2jar.ir.stmt.LabelStmt)39 Local (com.googlecode.dex2jar.ir.expr.Local)26 Stmt (com.googlecode.dex2jar.ir.stmt.Stmt)22 AssignStmt (com.googlecode.dex2jar.ir.stmt.AssignStmt)17 Test (org.junit.Test)14 Value (com.googlecode.dex2jar.ir.expr.Value)8 ArrayList (java.util.ArrayList)7 Trap (com.googlecode.dex2jar.ir.Trap)4 JumpStmt (com.googlecode.dex2jar.ir.stmt.JumpStmt)4 StmtList (com.googlecode.dex2jar.ir.stmt.StmtList)4 List (java.util.List)3 StmtTraveler (com.googlecode.dex2jar.ir.StmtTraveler)2 PhiExpr (com.googlecode.dex2jar.ir.expr.PhiExpr)2 Cfg (com.googlecode.dex2jar.ir.ts.Cfg)2 HashSet (java.util.HashSet)2 IR2JConverter (com.googlecode.d2j.converter.IR2JConverter)1 DexFileNode (com.googlecode.d2j.node.DexFileNode)1 DexMethodNode (com.googlecode.d2j.node.DexMethodNode)1 IrMethod (com.googlecode.dex2jar.ir.IrMethod)1 LabelAndLocalMapper (com.googlecode.dex2jar.ir.LabelAndLocalMapper)1