Search in sources :

Example 51 with AssignStmt

use of soot.jimple.AssignStmt in project soot by Sable.

the class ConstantInitializerToTagTransformer method transformClass.

/**
 * Transforms the given class, i.e. scans for a <clinit> method and
 * generates new constant value tags for all constant assignments to static
 * final fields.
 *
 * @param sc
 *            The class to transform
 * @param removeAssignments
 *            True if the assignments inside the <clinit> method shall be
 *            removed, otherwise false
 */
public void transformClass(SootClass sc, boolean removeAssignments) {
    // If this class has no <clinit> method, we're done
    SootMethod smInit = sc.getMethodByNameUnsafe("<clinit>");
    if (smInit == null || !smInit.isConcrete())
        return;
    Set<SootField> nonConstantFields = new HashSet<SootField>();
    Map<SootField, ConstantValueTag> newTags = new HashMap<SootField, ConstantValueTag>();
    // in case of
    Set<SootField> removeTagList = new HashSet<SootField>();
    for (Iterator<Unit> itU = smInit.getActiveBody().getUnits().snapshotIterator(); itU.hasNext(); ) {
        Unit u = itU.next();
        if (u instanceof AssignStmt) {
            AssignStmt assign = (AssignStmt) u;
            if (assign.getLeftOp() instanceof StaticFieldRef && assign.getRightOp() instanceof Constant) {
                SootField field = null;
                try {
                    field = ((StaticFieldRef) assign.getLeftOp()).getField();
                    if (field == null || nonConstantFields.contains(field))
                        continue;
                } catch (ConflictingFieldRefException ex) {
                    // Ignore this statement
                    continue;
                }
                if (field.getDeclaringClass().equals(sc) && field.isStatic() && field.isFinal()) {
                    // Do we already have a constant value for this field?
                    boolean found = false;
                    for (Tag t : field.getTags()) {
                        if (t instanceof ConstantValueTag) {
                            if (checkConstantValue((ConstantValueTag) t, (Constant) assign.getRightOp())) {
                                // the assignment.
                                if (removeAssignments)
                                    itU.remove();
                            } else {
                                logger.debug("" + "WARNING: Constant value for field '" + field + "' mismatch between code (" + assign.getRightOp() + ") and constant table (" + t + ")");
                                removeTagList.add(field);
                            }
                            found = true;
                            break;
                        }
                    }
                    if (!found) {
                        // tags.
                        if (!checkConstantValue(newTags.get(field), (Constant) assign.getRightOp())) {
                            nonConstantFields.add(field);
                            newTags.remove(field);
                            removeTagList.add(field);
                            continue;
                        }
                        ConstantValueTag newTag = createConstantTagFromValue((Constant) assign.getRightOp());
                        if (newTag != null)
                            newTags.put(field, newTag);
                    }
                }
            } else if (assign.getLeftOp() instanceof StaticFieldRef) {
                // a non-constant is assigned to the field
                try {
                    SootField sf = ((StaticFieldRef) assign.getLeftOp()).getField();
                    if (sf != null)
                        removeTagList.add(sf);
                } catch (ConflictingFieldRefException ex) {
                // let's assume that a broken field doesn't cause any
                // harm
                }
            }
        }
    }
    // Do the actual assignment
    for (Entry<SootField, ConstantValueTag> entry : newTags.entrySet()) {
        SootField field = entry.getKey();
        if (removeTagList.contains(field))
            continue;
        field.addTag(entry.getValue());
    }
    if (removeAssignments && !newTags.isEmpty())
        for (Iterator<Unit> itU = smInit.getActiveBody().getUnits().snapshotIterator(); itU.hasNext(); ) {
            Unit u = itU.next();
            if (u instanceof AssignStmt) {
                AssignStmt assign = (AssignStmt) u;
                if (assign.getLeftOp() instanceof FieldRef)
                    try {
                        SootField fld = ((FieldRef) assign.getLeftOp()).getField();
                        if (fld != null && newTags.containsKey(fld))
                            itU.remove();
                    } catch (ConflictingFieldRefException ex) {
                    // Ignore broken code
                    }
            }
        }
    // remove constant tags
    for (SootField sf : removeTagList) {
        if (removeTagList.contains(sf)) {
            List<Tag> toRemoveTagList = new ArrayList<Tag>();
            for (Tag t : sf.getTags()) {
                if (t instanceof ConstantValueTag) {
                    toRemoveTagList.add(t);
                }
            }
            for (Tag t : toRemoveTagList) {
                sf.getTags().remove(t);
            }
        }
    }
}
Also used : FieldRef(soot.jimple.FieldRef) StaticFieldRef(soot.jimple.StaticFieldRef) HashMap(java.util.HashMap) AssignStmt(soot.jimple.AssignStmt) Constant(soot.jimple.Constant) LongConstant(soot.jimple.LongConstant) DoubleConstant(soot.jimple.DoubleConstant) IntConstant(soot.jimple.IntConstant) StringConstant(soot.jimple.StringConstant) FloatConstant(soot.jimple.FloatConstant) ArrayList(java.util.ArrayList) Unit(soot.Unit) ConflictingFieldRefException(soot.ConflictingFieldRefException) StaticFieldRef(soot.jimple.StaticFieldRef) ConstantValueTag(soot.tagkit.ConstantValueTag) DoubleConstantValueTag(soot.tagkit.DoubleConstantValueTag) FloatConstantValueTag(soot.tagkit.FloatConstantValueTag) IntegerConstantValueTag(soot.tagkit.IntegerConstantValueTag) StringConstantValueTag(soot.tagkit.StringConstantValueTag) LongConstantValueTag(soot.tagkit.LongConstantValueTag) Iterator(java.util.Iterator) SootMethod(soot.SootMethod) SootField(soot.SootField) Tag(soot.tagkit.Tag) ConstantValueTag(soot.tagkit.ConstantValueTag) DoubleConstantValueTag(soot.tagkit.DoubleConstantValueTag) FloatConstantValueTag(soot.tagkit.FloatConstantValueTag) IntegerConstantValueTag(soot.tagkit.IntegerConstantValueTag) StringConstantValueTag(soot.tagkit.StringConstantValueTag) LongConstantValueTag(soot.tagkit.LongConstantValueTag) HashSet(java.util.HashSet)

Example 52 with AssignStmt

use of soot.jimple.AssignStmt in project soot by Sable.

the class AsmMethodSource method assignReadOps.

private void assignReadOps(Local l) {
    if (stack.isEmpty())
        return;
    for (Operand opr : stack) {
        if (opr == DWORD_DUMMY || opr.stack != null || (l == null && opr.value instanceof Local))
            continue;
        if (l != null && !opr.value.equivTo(l)) {
            List<ValueBox> uses = opr.value.getUseBoxes();
            boolean noref = true;
            for (ValueBox use : uses) {
                Value val = use.getValue();
                if (val.equivTo(l)) {
                    noref = false;
                    break;
                }
            }
            if (noref)
                continue;
        }
        int op = opr.insn.getOpcode();
        if (l == null && op != GETFIELD && op != GETSTATIC && (op < IALOAD && op > SALOAD))
            continue;
        Local stack = newStackLocal();
        opr.stack = stack;
        AssignStmt as = Jimple.v().newAssignStmt(stack, opr.value);
        opr.updateBoxes();
        setUnit(opr.insn, as);
    }
}
Also used : ValueBox(soot.ValueBox) AssignStmt(soot.jimple.AssignStmt) Value(soot.Value) Local(soot.Local)

Example 53 with AssignStmt

use of soot.jimple.AssignStmt in project soot by Sable.

the class AsmMethodSource method convertPutFieldInsn.

private void convertPutFieldInsn(FieldInsnNode insn) {
    boolean instance = insn.getOpcode() == PUTFIELD;
    StackFrame frame = getFrame(insn);
    Operand[] out = frame.out();
    Operand opr, rvalue;
    Type type;
    if (out == null) {
        SootClass declClass = Scene.v().getSootClass(AsmUtil.toQualifiedName(insn.owner));
        type = AsmUtil.toJimpleType(insn.desc);
        Value val;
        SootFieldRef ref;
        rvalue = popImmediate(type);
        if (!instance) {
            ref = Scene.v().makeFieldRef(declClass, insn.name, type, true);
            val = Jimple.v().newStaticFieldRef(ref);
            frame.in(rvalue);
        } else {
            Operand base = popLocal();
            ref = Scene.v().makeFieldRef(declClass, insn.name, type, false);
            InstanceFieldRef ifr = Jimple.v().newInstanceFieldRef(base.stackOrValue(), ref);
            val = ifr;
            base.addBox(ifr.getBaseBox());
            frame.in(rvalue, base);
        }
        opr = new Operand(insn, val);
        frame.out(opr);
        AssignStmt as = Jimple.v().newAssignStmt(val, rvalue.stackOrValue());
        rvalue.addBox(as.getRightOpBox());
        if (!instance) {
            frame.boxes(as.getRightOpBox());
        } else {
            frame.boxes(as.getRightOpBox(), ((InstanceFieldRef) val).getBaseBox());
        }
        setUnit(insn, as);
    } else {
        opr = out[0];
        type = opr.<FieldRef>value().getFieldRef().type();
        rvalue = pop(type);
        if (!instance) {
            /* PUTSTATIC only needs one operand on the stack, the rvalue */
            frame.mergeIn(rvalue);
        } else {
            /* PUTFIELD has a rvalue and a base */
            frame.mergeIn(rvalue, pop());
        }
    }
    /*
		 * in case any static field or array is read from, and the static constructor
		 * or the field this instruction writes to, modifies that field, write out any
		 * previous read from field/array
		 */
    assignReadOps(null);
}
Also used : BooleanType(soot.BooleanType) Type(soot.Type) UnknownType(soot.UnknownType) ArrayType(soot.ArrayType) RefType(soot.RefType) ShortType(soot.ShortType) ByteType(soot.ByteType) DoubleType(soot.DoubleType) FloatType(soot.FloatType) IntType(soot.IntType) CharType(soot.CharType) LongType(soot.LongType) VoidType(soot.VoidType) AssignStmt(soot.jimple.AssignStmt) Value(soot.Value) InstanceFieldRef(soot.jimple.InstanceFieldRef) SootClass(soot.SootClass) SootFieldRef(soot.SootFieldRef)

Example 54 with AssignStmt

use of soot.jimple.AssignStmt in project soot by Sable.

the class AsmMethodSource method convertArrayStoreInsn.

private void convertArrayStoreInsn(InsnNode insn) {
    int op = insn.getOpcode();
    boolean dword = op == LASTORE || op == DASTORE;
    StackFrame frame = getFrame(insn);
    if (!units.containsKey(insn)) {
        Operand valu = dword ? popImmediateDual() : popImmediate();
        Operand indx = popImmediate();
        Operand base = popLocal();
        ArrayRef ar = Jimple.v().newArrayRef(base.stackOrValue(), indx.stackOrValue());
        indx.addBox(ar.getIndexBox());
        base.addBox(ar.getBaseBox());
        AssignStmt as = Jimple.v().newAssignStmt(ar, valu.stackOrValue());
        valu.addBox(as.getRightOpBox());
        frame.in(valu, indx, base);
        frame.boxes(as.getRightOpBox(), ar.getIndexBox(), ar.getBaseBox());
        setUnit(insn, as);
    } else {
        frame.mergeIn(dword ? popDual() : pop(), pop(), pop());
    }
}
Also used : ArrayRef(soot.jimple.ArrayRef) AssignStmt(soot.jimple.AssignStmt)

Example 55 with AssignStmt

use of soot.jimple.AssignStmt in project soot by Sable.

the class CastAndReturnInliner method internalTransform.

@Override
protected void internalTransform(Body body, String phaseName, Map<String, String> options) {
    Iterator<Unit> it = body.getUnits().snapshotIterator();
    while (it.hasNext()) {
        Unit u = it.next();
        if (u instanceof GotoStmt) {
            GotoStmt gtStmt = (GotoStmt) u;
            if (gtStmt.getTarget() instanceof AssignStmt) {
                AssignStmt assign = (AssignStmt) gtStmt.getTarget();
                if (assign.getRightOp() instanceof CastExpr) {
                    CastExpr ce = (CastExpr) assign.getRightOp();
                    // We have goto that ends up at a cast statement
                    Unit nextStmt = body.getUnits().getSuccOf(assign);
                    if (nextStmt instanceof ReturnStmt) {
                        ReturnStmt retStmt = (ReturnStmt) nextStmt;
                        if (retStmt.getOp() == assign.getLeftOp()) {
                            // We need to replace the GOTO with the return
                            ReturnStmt newStmt = (ReturnStmt) retStmt.clone();
                            newStmt.setOp(ce.getOp());
                            for (Trap t : body.getTraps()) for (UnitBox ubox : t.getUnitBoxes()) if (ubox.getUnit() == gtStmt)
                                ubox.setUnit(newStmt);
                            while (!gtStmt.getBoxesPointingToThis().isEmpty()) gtStmt.getBoxesPointingToThis().get(0).setUnit(newStmt);
                            body.getUnits().swapWith(gtStmt, newStmt);
                        }
                    }
                }
            }
        }
    }
}
Also used : UnitBox(soot.UnitBox) AssignStmt(soot.jimple.AssignStmt) GotoStmt(soot.jimple.GotoStmt) CastExpr(soot.jimple.CastExpr) Trap(soot.Trap) Unit(soot.Unit) ReturnStmt(soot.jimple.ReturnStmt)

Aggregations

AssignStmt (soot.jimple.AssignStmt)83 Local (soot.Local)50 Value (soot.Value)44 Unit (soot.Unit)40 Type (soot.Type)28 Stmt (soot.jimple.Stmt)24 InvokeExpr (soot.jimple.InvokeExpr)20 RefType (soot.RefType)19 ArrayRef (soot.jimple.ArrayRef)19 ArrayType (soot.ArrayType)17 CastExpr (soot.jimple.CastExpr)17 InvokeStmt (soot.jimple.InvokeStmt)17 ArrayList (java.util.ArrayList)15 IdentityStmt (soot.jimple.IdentityStmt)15 DefinitionStmt (soot.jimple.DefinitionStmt)13 FieldRef (soot.jimple.FieldRef)13 InstanceFieldRef (soot.jimple.InstanceFieldRef)13 IntConstant (soot.jimple.IntConstant)13 ReturnStmt (soot.jimple.ReturnStmt)13 HashSet (java.util.HashSet)12