Search in sources :

Example 16 with AssignStmt

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

the class AggTransformer method localCanExecFirst.

/**
     * dfs find find local and the first locationInsensitive Value
     * // TODO if can not merge, try adjust the stmt to fit the local
     */
private static void localCanExecFirst(Local local, Stmt target) throws MergeResult {
    switch(target.et) {
        // impossible
        case E0:
        case // no EnStmt yet
        En:
            throw FAIL;
        case E1:
            localCanExecFirst(local, target.getOp());
            break;
        case E2:
            AssignStmt as = (AssignStmt) target;
            Value op1 = as.getOp1();
            Value op2 = as.getOp2();
            switch(op1.vt) {
                case LOCAL:
                    localCanExecFirst(local, op2);
                    break;
                case FIELD:
                    localCanExecFirst(local, op1.getOp());
                // pass through
                case STATIC_FIELD:
                    localCanExecFirst(local, op2);
                    break;
                case ARRAY:
                    localCanExecFirst(local, op1.getOp1());
                    localCanExecFirst(local, op1.getOp2());
                    localCanExecFirst(local, op2);
                    break;
                default:
            }
            break;
    }
    throw FAIL;
}
Also used : AssignStmt(com.googlecode.dex2jar.ir.stmt.AssignStmt) Value(com.googlecode.dex2jar.ir.expr.Value)

Example 17 with AssignStmt

use of com.googlecode.dex2jar.ir.stmt.AssignStmt 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 18 with AssignStmt

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

the class UnSSATransformer method insertAssignPath.

private void insertAssignPath(StmtList stmts, Stmt from, LabelStmt labelStmt, List<AssignStmt> buff) {
    boolean insertBeforeFromStmt;
    if (from.exceptionHandlers != null && from.exceptionHandlers.contains(labelStmt)) {
        insertBeforeFromStmt = true;
    } else {
        switch(from.st) {
            case GOTO:
            case IF:
                JumpStmt jumpStmt = (JumpStmt) from;
                //
                insertBeforeFromStmt = jumpStmt.getTarget().equals(labelStmt);
                break;
            case TABLE_SWITCH:
            case LOOKUP_SWITCH:
                insertBeforeFromStmt = true;
                break;
            default:
                insertBeforeFromStmt = false;
                break;
        }
    }
    if (insertBeforeFromStmt) {
        for (AssignStmt as : buff) {
            stmts.insertBefore(from, as);
        }
    } else {
        for (AssignStmt as : buff) {
            stmts.insertAfter(from, as);
        }
    }
    LiveV[] frame = (LiveV[]) from.frame;
    List<LiveV> newLiveVs = new ArrayList<>(buff.size());
    for (AssignStmt as : buff) {
        Local left = (Local) as.getOp1();
        {
            LiveV liveV = new LiveV();
            liveV.local = left;
            liveV.used = true;
            newLiveVs.add(liveV);
        }
        RegAssign leftRegAssign = (RegAssign) left.tag;
        Local right = (Local) as.getOp2();
        int toSkip = right._ls_index;
        for (int i = 0; i < frame.length; i++) {
            if (i == toSkip) {
                continue;
            }
            LiveV v = frame[i];
            if (v != null && v.used) {
                RegAssign assign = (RegAssign) v.local.tag;
                assign.excludes.add(leftRegAssign);
                leftRegAssign.excludes.add(assign);
            }
        }
        for (AssignStmt as2 : buff) {
            RegAssign assign = (RegAssign) ((Local) as2.getOp1()).tag;
            assign.excludes.add(leftRegAssign);
            leftRegAssign.excludes.add(assign);
        }
    }
    LiveV[] newFrame = new LiveV[frame.length + newLiveVs.size()];
    System.arraycopy(frame, 0, newFrame, 0, frame.length);
    for (int i = 0; i < newLiveVs.size(); i++) {
        newFrame[i + frame.length] = newLiveVs.get(i);
    }
}
Also used : JumpStmt(com.googlecode.dex2jar.ir.stmt.JumpStmt) AssignStmt(com.googlecode.dex2jar.ir.stmt.AssignStmt) ArrayList(java.util.ArrayList) Local(com.googlecode.dex2jar.ir.expr.Local)

Example 19 with AssignStmt

use of com.googlecode.dex2jar.ir.stmt.AssignStmt 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 20 with AssignStmt

use of com.googlecode.dex2jar.ir.stmt.AssignStmt 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)

Aggregations

AssignStmt (com.googlecode.dex2jar.ir.stmt.AssignStmt)22 LabelStmt (com.googlecode.dex2jar.ir.stmt.LabelStmt)18 Stmt (com.googlecode.dex2jar.ir.stmt.Stmt)13 Local (com.googlecode.dex2jar.ir.expr.Local)12 Value (com.googlecode.dex2jar.ir.expr.Value)11 ArrayList (java.util.ArrayList)6 JumpStmt (com.googlecode.dex2jar.ir.stmt.JumpStmt)4 StmtList (com.googlecode.dex2jar.ir.stmt.StmtList)3 Cfg (com.googlecode.dex2jar.ir.ts.Cfg)3 List (java.util.List)3 StmtTraveler (com.googlecode.dex2jar.ir.StmtTraveler)2 PhiExpr (com.googlecode.dex2jar.ir.expr.PhiExpr)2 HashSet (java.util.HashSet)2 Trap (com.googlecode.dex2jar.ir.Trap)1 Constant (com.googlecode.dex2jar.ir.expr.Constant)1 UnopStmt (com.googlecode.dex2jar.ir.stmt.UnopStmt)1 AnalyzeValue (com.googlecode.dex2jar.ir.ts.an.AnalyzeValue)1 HashMap (java.util.HashMap)1 Test (org.junit.Test)1