Search in sources :

Example 16 with JimpleBody

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

the class TypeAssigner method compareTypeAssigners.

private void compareTypeAssigners(Body b, boolean useOlderTypeAssigner) {
    JimpleBody jb = (JimpleBody) b, oldJb, newJb;
    int size = jb.getUnits().size();
    long oldTime, newTime;
    if (useOlderTypeAssigner) {
        // Use old type assigner last
        newJb = (JimpleBody) jb.clone();
        newTime = System.currentTimeMillis();
        (new soot.jimple.toolkits.typing.fast.TypeResolver(newJb)).inferTypes();
        newTime = System.currentTimeMillis() - newTime;
        oldTime = System.currentTimeMillis();
        TypeResolver.resolve(jb, Scene.v());
        oldTime = System.currentTimeMillis() - oldTime;
        oldJb = jb;
    } else {
        // Use new type assigner last
        oldJb = (JimpleBody) jb.clone();
        oldTime = System.currentTimeMillis();
        TypeResolver.resolve(oldJb, Scene.v());
        oldTime = System.currentTimeMillis() - oldTime;
        newTime = System.currentTimeMillis();
        (new soot.jimple.toolkits.typing.fast.TypeResolver(jb)).inferTypes();
        newTime = System.currentTimeMillis() - newTime;
        newJb = jb;
    }
    int cmp;
    if (newJb.getLocals().size() < oldJb.getLocals().size())
        cmp = 2;
    else if (newJb.getLocals().size() > oldJb.getLocals().size())
        cmp = -2;
    else
        cmp = compareTypings(oldJb, newJb);
    logger.debug("cmp;" + jb.getMethod() + ";" + size + ";" + oldTime + ";" + newTime + ";" + cmp);
}
Also used : JimpleBody(soot.jimple.JimpleBody)

Example 17 with JimpleBody

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

the class ConstructorDecl method jimplify2.

/**
 * @ast method
 * @aspect EmitJimpleRefinements
 * @declaredat /Users/eric/Documents/workspaces/clara-soot/JastAddExtensions/SootJastAddJ/EmitJimpleRefinements.jrag:121
 */
public void jimplify2() {
    if (!generate() || sootMethod().hasActiveBody() || (sootMethod().getSource() != null && (sootMethod().getSource() instanceof soot.coffi.CoffiMethodSource)))
        return;
    JimpleBody body = Jimple.v().newBody(sootMethod());
    sootMethod().setActiveBody(body);
    Body b = new Body(hostType(), body, this);
    b.setLine(this);
    for (int i = 0; i < getNumParameter(); i++) getParameter(i).jimplify2(b);
    boolean needsInit = true;
    if (hasConstructorInvocation()) {
        getConstructorInvocation().jimplify2(b);
        Stmt stmt = getConstructorInvocation();
        if (stmt instanceof ExprStmt) {
            ExprStmt exprStmt = (ExprStmt) stmt;
            Expr expr = exprStmt.getExpr();
            if (!expr.isSuperConstructorAccess())
                needsInit = false;
        }
    }
    if (hostType().needsEnclosing()) {
        TypeDecl type = hostType().enclosingType();
        b.add(Jimple.v().newAssignStmt(Jimple.v().newInstanceFieldRef(b.emitThis(hostType()), hostType().getSootField("this$0", type).makeRef()), asLocal(b, Jimple.v().newParameterRef(type.getSootType(), 0))));
    }
    for (Iterator iter = hostType().enclosingVariables().iterator(); iter.hasNext(); ) {
        Variable v = (Variable) iter.next();
        ParameterDeclaration p = (ParameterDeclaration) parameterDeclaration("val$" + v.name()).iterator().next();
        b.add(Jimple.v().newAssignStmt(Jimple.v().newInstanceFieldRef(b.emitThis(hostType()), Scene.v().makeFieldRef(hostType().getSootClassDecl(), "val$" + v.name(), v.type().getSootType(), false)), p.local));
    }
    if (needsInit) {
        TypeDecl typeDecl = hostType();
        for (int i = 0; i < typeDecl.getNumBodyDecl(); i++) {
            BodyDecl bodyDecl = typeDecl.getBodyDecl(i);
            if (bodyDecl instanceof FieldDeclaration && bodyDecl.generate()) {
                FieldDeclaration f = (FieldDeclaration) bodyDecl;
                if (!f.isStatic() && f.hasInit()) {
                    soot.Local base = b.emitThis(hostType());
                    Local l = asLocal(// AssignConversion
                    b, // AssignConversion
                    f.getInit().type().emitCastTo(b, f.getInit(), f.type()), f.type().getSootType());
                    b.setLine(f);
                    b.add(Jimple.v().newAssignStmt(Jimple.v().newInstanceFieldRef(base, f.sootRef()), l));
                }
            } else if (bodyDecl instanceof InstanceInitializer && bodyDecl.generate()) {
                bodyDecl.jimplify2(b);
            }
        }
    }
    getBlock().jimplify2(b);
    b.add(Jimple.v().newReturnVoidStmt());
}
Also used : Local(soot.Local) Iterator(java.util.Iterator) JimpleBody(soot.jimple.JimpleBody) JimpleBody(soot.jimple.JimpleBody) Local(soot.Local)

Example 18 with JimpleBody

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

the class MethodDecl method jimplify2.

/**
 * @ast method
 * @aspect EmitJimpleRefinements
 * @declaredat /Users/eric/Documents/workspaces/clara-soot/JastAddExtensions/SootJastAddJ/EmitJimpleRefinements.jrag:100
 */
public void jimplify2() {
    if (!generate() || sootMethod().hasActiveBody() || (sootMethod().getSource() != null && (sootMethod().getSource() instanceof soot.coffi.CoffiMethodSource)))
        return;
    try {
        if (hasBlock() && !(hostType().isInterfaceDecl())) {
            JimpleBody body = Jimple.v().newBody(sootMethod());
            sootMethod().setActiveBody(body);
            Body b = new Body(hostType(), body, this);
            b.setLine(this);
            for (int i = 0; i < getNumParameter(); i++) getParameter(i).jimplify2(b);
            getBlock().jimplify2(b);
            if (type() instanceof VoidType)
                b.add(Jimple.v().newReturnVoidStmt());
        }
    } catch (RuntimeException e) {
        System.err.println("Error generating " + hostType().typeName() + ": " + this);
        throw e;
    }
}
Also used : JimpleBody(soot.jimple.JimpleBody) JimpleBody(soot.jimple.JimpleBody)

Example 19 with JimpleBody

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

the class AbstractASMBackend method getBafBody.

/**
 * Gets the baf body for the given SootMethod. This method will first check
 * whether the method already has a baf body. If not, it will query the local
 * cache. If this fails as well, it will construct a new baf body.
 * @param method The method for which to obtain a baf body
 * @return The baf body for the given method
 */
protected BafBody getBafBody(SootMethod method) {
    final Body activeBody = method.getActiveBody();
    if (activeBody instanceof BafBody)
        return (BafBody) activeBody;
    BafBody body = bafBodyCache.get(method);
    if (body != null)
        return body;
    if (activeBody instanceof JimpleBody) {
        body = PackManager.v().convertJimpleBodyToBaf(method);
    } else {
        throw new RuntimeException("ASM-backend can only translate Baf- and JimpleBodies!");
    }
    bafBodyCache.put(method, body);
    return body;
}
Also used : BafBody(soot.baf.BafBody) JimpleBody(soot.jimple.JimpleBody) BafBody(soot.baf.BafBody) JimpleBody(soot.jimple.JimpleBody)

Example 20 with JimpleBody

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

the class BuildIntermediateAppClasses method internalTransform.

protected void internalTransform(String phaseName, Map<String, String> options) {
    if (output) {
        out.println("Building Intermediate Classes...");
    }
    BodyBuilder.retrieveAllBodies();
    // iterate through application classes, build intermediate classes
    Iterator<SootClass> it = Scene.v().getApplicationClasses().snapshotIterator();
    while (it.hasNext()) {
        List<SootMethod> initMethodsToRewrite = new ArrayList<>();
        Map<String, SootMethod> methodsToAdd = new HashMap<>();
        SootClass sc = it.next();
        SootClass originalSuperclass = sc.getSuperclass();
        if (output) {
            out.println("Processing " + sc.getName() + " with super " + originalSuperclass.getName());
        }
        Iterator<SootMethod> methodIterator = sc.methodIterator();
        while (methodIterator.hasNext()) {
            SootMethod method = methodIterator.next();
            if (!method.isConcrete()) {
                continue;
            }
            try {
                method.getActiveBody();
            } catch (Exception e) {
                if (method.retrieveActiveBody() == null)
                    throw new RuntimeException(method.getSignature() + " has no body. This was not expected dude.");
            }
            String subSig = method.getSubSignature();
            if (subSig.equals("void main(java.lang.String[])") && method.isPublic() && method.isStatic()) {
                // skip the main method - it needs to be named 'main'
                continue;
            } else if (subSig.indexOf("init>(") > 0) {
                if (subSig.startsWith("void <init>(")) {
                    initMethodsToRewrite.add(method);
                }
                // skip constructors, just add for rewriting at the end
                continue;
            } else {
                Scene.v().releaseActiveHierarchy();
                findAccessibleInSuperClassesBySubSig(sc, subSig).ifPresent(m -> methodsToAdd.put(subSig, m));
            }
        }
        if (methodsToAdd.size() > 0) {
            final String fullName = ClassRenamer.v().getNewName(ClassRenamer.getPackageName(sc.getName()), null);
            if (output) {
                out.println("\tBuilding " + fullName);
            }
            // make non-final soot class
            SootClass mediatingClass = new SootClass(fullName, sc.getModifiers() & (~Modifier.FINAL));
            Main.IntermediateAppClasses.add(mediatingClass);
            mediatingClass.setSuperclass(originalSuperclass);
            Scene.v().addClass(mediatingClass);
            mediatingClass.setApplicationClass();
            mediatingClass.setInScene(true);
            ThisRef thisRef = new ThisRef(mediatingClass.getType());
            for (String subSig : methodsToAdd.keySet()) {
                SootMethod originalSuperclassMethod = methodsToAdd.get(subSig);
                List<Type> paramTypes = originalSuperclassMethod.getParameterTypes();
                Type returnType = originalSuperclassMethod.getReturnType();
                List<SootClass> exceptions = originalSuperclassMethod.getExceptions();
                int modifiers = originalSuperclassMethod.getModifiers() & ~Modifier.ABSTRACT & ~Modifier.NATIVE;
                SootMethod newMethod;
                {
                    // build new junk method to call original method
                    String newMethodName = MethodRenamer.v().getNewName();
                    newMethod = Scene.v().makeSootMethod(newMethodName, paramTypes, returnType, modifiers, exceptions);
                    mediatingClass.addMethod(newMethod);
                    Body body = Jimple.v().newBody(newMethod);
                    newMethod.setActiveBody(body);
                    Chain<Local> locals = body.getLocals();
                    PatchingChain<Unit> units = body.getUnits();
                    BodyBuilder.buildThisLocal(units, thisRef, locals);
                    BodyBuilder.buildParameterLocals(units, locals, paramTypes);
                    if (returnType instanceof VoidType) {
                        units.add(Jimple.v().newReturnVoidStmt());
                    } else if (returnType instanceof PrimType) {
                        units.add(Jimple.v().newReturnStmt(IntConstant.v(0)));
                    } else {
                        units.add(Jimple.v().newReturnStmt(NullConstant.v()));
                    }
                    newmethods++;
                }
                // end build new junk method to call original method
                {
                    // build copy of old method
                    newMethod = Scene.v().makeSootMethod(originalSuperclassMethod.getName(), paramTypes, returnType, modifiers, exceptions);
                    mediatingClass.addMethod(newMethod);
                    Body body = Jimple.v().newBody(newMethod);
                    newMethod.setActiveBody(body);
                    Chain<Local> locals = body.getLocals();
                    PatchingChain<Unit> units = body.getUnits();
                    Local ths = BodyBuilder.buildThisLocal(units, thisRef, locals);
                    List<Local> args = BodyBuilder.buildParameterLocals(units, locals, paramTypes);
                    SootMethodRef superclassMethodRef = originalSuperclassMethod.makeRef();
                    if (returnType instanceof VoidType) {
                        units.add(Jimple.v().newInvokeStmt(Jimple.v().newSpecialInvokeExpr(ths, superclassMethodRef, args)));
                        units.add(Jimple.v().newReturnVoidStmt());
                    } else {
                        Local loc = Jimple.v().newLocal("retValue", returnType);
                        body.getLocals().add(loc);
                        units.add(Jimple.v().newAssignStmt(loc, Jimple.v().newSpecialInvokeExpr(ths, superclassMethodRef, args)));
                        units.add(Jimple.v().newReturnStmt(loc));
                    }
                    newmethods++;
                }
            // end build copy of old method
            }
            sc.setSuperclass(mediatingClass);
            // rewrite class init methods to call the proper superclass inits
            int i = initMethodsToRewrite.size();
            while (i-- > 0) {
                SootMethod im = initMethodsToRewrite.remove(i);
                Body b = im.getActiveBody();
                Local thisLocal = b.getThisLocal();
                Iterator<Unit> uIt = b.getUnits().snapshotIterator();
                while (uIt.hasNext()) {
                    for (ValueBox valueBox : uIt.next().getUseBoxes()) {
                        Value v = valueBox.getValue();
                        if (v instanceof SpecialInvokeExpr) {
                            SpecialInvokeExpr sie = (SpecialInvokeExpr) v;
                            SootMethodRef smr = sie.getMethodRef();
                            if (sie.getBase().equivTo(thisLocal) && smr.declaringClass().getName().equals(originalSuperclass.getName()) && smr.getSubSignature().getString().startsWith("void " + constructorName)) {
                                SootMethod newSuperInit;
                                if (!mediatingClass.declaresMethod(constructorName, smr.parameterTypes())) {
                                    List<Type> paramTypes = smr.parameterTypes();
                                    newSuperInit = Scene.v().makeSootMethod(constructorName, paramTypes, smr.returnType());
                                    mediatingClass.addMethod(newSuperInit);
                                    JimpleBody body = Jimple.v().newBody(newSuperInit);
                                    newSuperInit.setActiveBody(body);
                                    PatchingChain<Unit> initUnits = body.getUnits();
                                    Collection<Local> locals = body.getLocals();
                                    Local ths = BodyBuilder.buildThisLocal(initUnits, thisRef, locals);
                                    List<Local> args = BodyBuilder.buildParameterLocals(initUnits, locals, paramTypes);
                                    initUnits.add(Jimple.v().newInvokeStmt(Jimple.v().newSpecialInvokeExpr(ths, smr, args)));
                                    initUnits.add(Jimple.v().newReturnVoidStmt());
                                } else {
                                    newSuperInit = mediatingClass.getMethod(constructorName, smr.parameterTypes());
                                }
                                sie.setMethodRef(newSuperInit.makeRef());
                            }
                        }
                    }
                }
            }
        // end of rewrite class init methods to call the proper superclass inits
        }
    }
    newclasses = Main.IntermediateAppClasses.size();
    Scene.v().releaseActiveHierarchy();
    Scene.v().getActiveHierarchy();
    Scene.v().setFastHierarchy(new FastHierarchy());
}
Also used : Body(soot.Body) ThisRef(soot.jimple.ThisRef) PatchingChain(soot.PatchingChain) Main(soot.jbco.Main) BodyBuilder(soot.jbco.util.BodyBuilder) HashMap(java.util.HashMap) NullConstant(soot.jimple.NullConstant) FastHierarchy(soot.FastHierarchy) Modifier(soot.Modifier) SootMethodRef(soot.SootMethodRef) ArrayList(java.util.ArrayList) SootMethod(soot.SootMethod) IJbcoTransform(soot.jbco.IJbcoTransform) Chain(soot.util.Chain) Map(java.util.Map) Local(soot.Local) Scene(soot.Scene) IntConstant(soot.jimple.IntConstant) Value(soot.Value) SpecialInvokeExpr(soot.jimple.SpecialInvokeExpr) Iterator(java.util.Iterator) Unit(soot.Unit) Collection(java.util.Collection) Jimple(soot.jimple.Jimple) SootClass(soot.SootClass) ValueBox(soot.ValueBox) Type(soot.Type) List(java.util.List) JimpleBody(soot.jimple.JimpleBody) SootMethod.constructorName(soot.SootMethod.constructorName) PrimType(soot.PrimType) VoidType(soot.VoidType) Hierarchy(soot.Hierarchy) Optional(java.util.Optional) SceneTransformer(soot.SceneTransformer) VoidType(soot.VoidType) PatchingChain(soot.PatchingChain) Chain(soot.util.Chain) HashMap(java.util.HashMap) SpecialInvokeExpr(soot.jimple.SpecialInvokeExpr) ArrayList(java.util.ArrayList) Unit(soot.Unit) PrimType(soot.PrimType) ArrayList(java.util.ArrayList) List(java.util.List) Body(soot.Body) JimpleBody(soot.jimple.JimpleBody) JimpleBody(soot.jimple.JimpleBody) PatchingChain(soot.PatchingChain) SootMethodRef(soot.SootMethodRef) Local(soot.Local) SootClass(soot.SootClass) Type(soot.Type) PrimType(soot.PrimType) VoidType(soot.VoidType) FastHierarchy(soot.FastHierarchy) ThisRef(soot.jimple.ThisRef) ValueBox(soot.ValueBox) Value(soot.Value) SootMethod(soot.SootMethod)

Aggregations

JimpleBody (soot.jimple.JimpleBody)23 Local (soot.Local)14 SootMethod (soot.SootMethod)13 Unit (soot.Unit)10 ArrayList (java.util.ArrayList)9 SootClass (soot.SootClass)9 Iterator (java.util.Iterator)7 Value (soot.Value)7 Stmt (soot.jimple.Stmt)7 RefType (soot.RefType)6 List (java.util.List)5 VoidType (soot.VoidType)5 HashMap (java.util.HashMap)4 LinkedList (java.util.LinkedList)4 Body (soot.Body)4 BooleanType (soot.BooleanType)4 ByteType (soot.ByteType)4 CharType (soot.CharType)4 DoubleType (soot.DoubleType)4 FloatType (soot.FloatType)4