Search in sources :

Example 1 with DirectedGraph

use of soot.toolkits.graph.DirectedGraph in project soot by Sable.

the class CFGGraphType method loadAltGraph.

private static DirectedGraph loadAltGraph(String className, Body b) {
    try {
        Class<?> graphClass = AltClassLoader.v().loadClass(className);
        Class<?>[] paramTypes = new Class[] { Body.class };
        Constructor constructor = graphClass.getConstructor(paramTypes);
        DirectedGraph result = (DirectedGraph) constructor.newInstance(new Object[] { b });
        return result;
    }// don't need to declare them:  perhaps a shoddy tactic.
     catch (ClassNotFoundException e) {
        if (DEBUG) {
            logger.error(e.getMessage(), e);
        }
        throw new IllegalArgumentException("Unable to find " + className + " in alternate classpath: " + e.getMessage());
    } catch (NoSuchMethodException e) {
        if (DEBUG) {
            logger.error(e.getMessage(), e);
        }
        throw new IllegalArgumentException("There is no " + className + "(Body) constructor: " + e.getMessage());
    } catch (InstantiationException e) {
        if (DEBUG) {
            logger.error(e.getMessage(), e);
        }
        throw new IllegalArgumentException("Unable to instantiate " + className + " in alternate classpath: " + e.getMessage());
    } catch (IllegalAccessException e) {
        if (DEBUG) {
            logger.error(e.getMessage(), e);
        }
        throw new IllegalArgumentException("Unable to access " + className + "(Body) in alternate classpath: " + e.getMessage());
    } catch (InvocationTargetException e) {
        if (DEBUG) {
            logger.error(e.getMessage(), e);
        }
        throw new IllegalArgumentException("Unable to invoke " + className + "(Body) in alternate classpath: " + e.getMessage());
    }
}
Also used : Constructor(java.lang.reflect.Constructor) InvocationTargetException(java.lang.reflect.InvocationTargetException) DirectedGraph(soot.toolkits.graph.DirectedGraph) Body(soot.Body)

Example 2 with DirectedGraph

use of soot.toolkits.graph.DirectedGraph in project soot by Sable.

the class GroupIntPair method emitMethodBody.

@Override
protected void emitMethodBody(SootMethod method) {
    if (Options.v().time())
        Timers.v().buildJasminTimer.end();
    Body activeBody = method.getActiveBody();
    if (!(activeBody instanceof BafBody)) {
        if (activeBody instanceof JimpleBody) {
            if (Options.v().verbose()) {
                logger.debug("Was expecting Baf body for " + method + " but found a Jimple body. Will convert body to Baf on the fly.");
            }
            activeBody = PackManager.v().convertJimpleBodyToBaf(method);
        } else
            throw new RuntimeException("method: " + method.getName() + " has an invalid active body!");
    }
    BafBody body = (BafBody) activeBody;
    if (body == null)
        throw new RuntimeException("method: " + method.getName() + " has no active body!");
    if (Options.v().time())
        Timers.v().buildJasminTimer.start();
    Chain<Unit> instList = body.getUnits();
    int stackLimitIndex = -1;
    subroutineToReturnAddressSlot = new HashMap<Unit, Integer>(10, 0.7f);
    // Determine the unitToLabel map
    {
        unitToLabel = new HashMap<Unit, String>(instList.size() * 2 + 1, 0.7f);
        labelCount = 0;
        for (UnitBox uBox : body.getUnitBoxes(true)) {
            // Assign a label for each statement reference
            {
                InstBox box = (InstBox) uBox;
                if (!unitToLabel.containsKey(box.getUnit()))
                    unitToLabel.put(box.getUnit(), "label" + labelCount++);
            }
        }
    }
    // Emit the exceptions, recording the Units at the beginning
    // of handlers so that later on we can recognize blocks that
    // begin with an exception on the stack.
    Set<Unit> handlerUnits = new ArraySet<Unit>(body.getTraps().size());
    {
        for (Trap trap : body.getTraps()) {
            handlerUnits.add(trap.getHandlerUnit());
            if (trap.getBeginUnit() != trap.getEndUnit()) {
                emit(".catch " + slashify(trap.getException().getName()) + " from " + unitToLabel.get(trap.getBeginUnit()) + " to " + unitToLabel.get(trap.getEndUnit()) + " using " + unitToLabel.get(trap.getHandlerUnit()));
            }
        }
    }
    // Determine where the locals go
    {
        int localCount = 0;
        int[] paramSlots = new int[method.getParameterCount()];
        int thisSlot = 0;
        Set<Local> assignedLocals = new HashSet<Local>();
        localToSlot = new HashMap<Local, Integer>(body.getLocalCount() * 2 + 1, 0.7f);
        // assignColorsToLocals(body);
        // Determine slots for 'this' and parameters
        {
            if (!method.isStatic()) {
                thisSlot = 0;
                localCount++;
            }
            for (int i = 0; i < method.getParameterCount(); i++) {
                paramSlots[i] = localCount;
                localCount += sizeOfType(method.getParameterType(i));
            }
        }
        // Handle identity statements
        {
            for (Unit u : instList) {
                Inst s = (Inst) u;
                if (s instanceof IdentityInst && ((IdentityInst) s).getLeftOp() instanceof Local) {
                    Local l = (Local) ((IdentityInst) s).getLeftOp();
                    IdentityRef identity = (IdentityRef) ((IdentityInst) s).getRightOp();
                    int slot = 0;
                    if (identity instanceof ThisRef) {
                        if (method.isStatic())
                            throw new RuntimeException("Attempting to use 'this' in static method");
                        slot = thisSlot;
                    } else if (identity instanceof ParameterRef)
                        slot = paramSlots[((ParameterRef) identity).getIndex()];
                    else {
                        // Exception ref. Skip over this
                        continue;
                    }
                    localToSlot.put(l, new Integer(slot));
                    assignedLocals.add(l);
                }
            }
        }
        // Assign the rest of the locals
        {
            for (Local local : body.getLocals()) {
                if (assignedLocals.add(local)) {
                    localToSlot.put(local, new Integer(localCount));
                    localCount += sizeOfType(local.getType());
                }
            }
            if (!Modifier.isNative(method.getModifiers()) && !Modifier.isAbstract(method.getModifiers())) {
                emit("    .limit stack ?");
                stackLimitIndex = code.size() - 1;
                emit("    .limit locals " + localCount);
            }
        }
    }
    // Emit code in one pass
    {
        isEmittingMethodCode = true;
        maxStackHeight = 0;
        isNextGotoAJsr = false;
        for (Unit u : instList) {
            Inst s = (Inst) u;
            if (unitToLabel.containsKey(s))
                emit(unitToLabel.get(s) + ":");
            // emit this statement
            {
                emitInst(s);
            }
        }
        isEmittingMethodCode = false;
        // calculate max stack height
        {
            maxStackHeight = 0;
            if (activeBody.getUnits().size() != 0) {
                BlockGraph blockGraph = new BriefBlockGraph(activeBody);
                List<Block> blocks = blockGraph.getBlocks();
                if (blocks.size() != 0) {
                    // set the stack height of the entry points
                    List<Block> entryPoints = ((DirectedGraph<Block>) blockGraph).getHeads();
                    for (Block entryBlock : entryPoints) {
                        Integer initialHeight;
                        if (handlerUnits.contains(entryBlock.getHead())) {
                            initialHeight = new Integer(1);
                        } else {
                            initialHeight = new Integer(0);
                        }
                        if (blockToStackHeight == null) {
                            blockToStackHeight = new HashMap<Block, Integer>();
                        }
                        blockToStackHeight.put(entryBlock, initialHeight);
                        if (blockToLogicalStackHeight == null) {
                            blockToLogicalStackHeight = new HashMap<Block, Integer>();
                        }
                        blockToLogicalStackHeight.put(entryBlock, initialHeight);
                    }
                    // entryPoints list as roots
                    for (Block nextBlock : entryPoints) {
                        calculateStackHeight(nextBlock);
                        calculateLogicalStackHeightCheck(nextBlock);
                    }
                }
            }
        }
        if (!Modifier.isNative(method.getModifiers()) && !Modifier.isAbstract(method.getModifiers()))
            code.set(stackLimitIndex, "    .limit stack " + maxStackHeight);
    }
    // emit code attributes
    {
        for (Tag t : body.getTags()) {
            if (t instanceof JasminAttribute) {
                emit(".code_attribute " + t.getName() + " \"" + ((JasminAttribute) t).getJasminValue(unitToLabel) + "\"");
            }
        }
    }
}
Also used : HashSet(java.util.HashSet) ArraySet(soot.util.ArraySet) Set(java.util.Set) HashMap(java.util.HashMap) Unit(soot.Unit) BriefBlockGraph(soot.toolkits.graph.BriefBlockGraph) BlockGraph(soot.toolkits.graph.BlockGraph) BriefBlockGraph(soot.toolkits.graph.BriefBlockGraph) DirectedGraph(soot.toolkits.graph.DirectedGraph) Body(soot.Body) UnitBox(soot.UnitBox) ArraySet(soot.util.ArraySet) Local(soot.Local) Trap(soot.Trap) JasminAttribute(soot.tagkit.JasminAttribute) Block(soot.toolkits.graph.Block) Tag(soot.tagkit.Tag) LineNumberTag(soot.tagkit.LineNumberTag)

Aggregations

Body (soot.Body)2 DirectedGraph (soot.toolkits.graph.DirectedGraph)2 Constructor (java.lang.reflect.Constructor)1 InvocationTargetException (java.lang.reflect.InvocationTargetException)1 HashMap (java.util.HashMap)1 HashSet (java.util.HashSet)1 Set (java.util.Set)1 Local (soot.Local)1 Trap (soot.Trap)1 Unit (soot.Unit)1 UnitBox (soot.UnitBox)1 JasminAttribute (soot.tagkit.JasminAttribute)1 LineNumberTag (soot.tagkit.LineNumberTag)1 Tag (soot.tagkit.Tag)1 Block (soot.toolkits.graph.Block)1 BlockGraph (soot.toolkits.graph.BlockGraph)1 BriefBlockGraph (soot.toolkits.graph.BriefBlockGraph)1 ArraySet (soot.util.ArraySet)1