Search in sources :

Example 6 with Block

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

the class RegionAnalysis method weakRegionDFS2.

/**
 * This algorithm starts from a head node in the CFG and is exactly the same as the above
 * with the difference that post dominator and dominator trees switch positions.
 * @param v
 * @param r
 */
private void weakRegionDFS2(Block v, int r) {
    // regions keep an implicit order of the contained blocks so it matters where blocks are added
    // below.
    this.m_regions.get(r).add2Back(v);
    DominatorNode<Block> parentOfV = this.m_pdom.getParentOf(this.m_pdom.getDode(v));
    Block u2 = (parentOfV == null) ? null : parentOfV.getGode();
    List<DominatorNode<Block>> children = this.m_dom.getChildrenOf(this.m_dom.getDode(v));
    for (int i = 0; i < children.size(); i++) {
        DominatorNode<Block> w = children.get(i);
        Block u1 = w.getGode();
        if (u2 != null && u1.equals(u2)) {
            this.weakRegionDFS2(w.getGode(), r);
        } else {
            this.m_regCount++;
            this.m_regions.put(this.m_regCount, this.createRegion(this.m_regCount));
            this.weakRegionDFS2(w.getGode(), this.m_regCount);
        }
    }
}
Also used : Block(soot.toolkits.graph.Block) DominatorNode(soot.toolkits.graph.DominatorNode)

Example 7 with Block

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

the class RegionAnalysis method getBlock2RegionMap.

public Hashtable<Block, Region> getBlock2RegionMap() {
    if (this.m_block2region == null) {
        this.m_block2region = new Hashtable<Block, Region>();
        List<Region> regions = this.getRegions();
        for (Iterator<Region> itr = regions.iterator(); itr.hasNext(); ) {
            Region r = itr.next();
            List<Block> blocks = r.getBlocks();
            for (Iterator<Block> itr1 = blocks.iterator(); itr1.hasNext(); ) {
                Block u = itr1.next();
                m_block2region.put(u, r);
            }
        }
    }
    return this.m_block2region;
}
Also used : Block(soot.toolkits.graph.Block)

Example 8 with Block

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

the class RegionAnalysis method weakRegionDFS.

/**
 * This algorithms assumes that the first time it's called with a tail of the CFG. Then for each
 * child node w of v in the post-dominator tree, it compares the parent of v in the dominator tree
 * with w and if they are the same, that means w belongs to the same region as v, so  weakRegionDFS
 * is recursively called with w and the same region id as v.
 * If the comparison fails, then a new region is created and weakRegionDFS is called recursively with
 * w but this time with the newly created region id.
 *
 * @param v
 * @param r
 */
private void weakRegionDFS(Block v, int r) {
    try {
        // System.out.println("##entered weakRegionDFS for region " + r);
        this.m_regions.get(r).add(v);
        DominatorNode<Block> parentOfV = this.m_dom.getParentOf(this.m_dom.getDode(v));
        Block u2 = (parentOfV == null) ? null : parentOfV.getGode();
        List<DominatorNode<Block>> children = this.m_pdom.getChildrenOf(this.m_pdom.getDode(v));
        for (int i = 0; i < children.size(); i++) {
            DominatorNode<Block> w = children.get(i);
            Block u1 = w.getGode();
            if (u2 != null && u1.equals(u2)) {
                this.weakRegionDFS(w.getGode(), r);
            } else {
                this.m_regCount++;
                this.m_regions.put(this.m_regCount, this.createRegion(this.m_regCount));
                this.weakRegionDFS(w.getGode(), this.m_regCount);
            }
        }
    } catch (RuntimeException e) {
        logger.debug("[RegionAnalysis] Exception in weakRegionDFS: ", e);
        logger.debug("v is  " + v.toShortString() + " in region " + r);
        G.v().out.flush();
    }
}
Also used : Block(soot.toolkits.graph.Block) DominatorNode(soot.toolkits.graph.DominatorNode)

Example 9 with Block

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

the class CFGToDotGraph method formatNodeText.

/**
 * A utility method which formats the text for each node in
 * a <code>DotGraph</code> representing a CFG.
 *
 * @param body the <code>Body</code> whose control flow is visualized in
 *             <code>canvas</code>.
 *
 * @param canvas the <code>DotGraph</code> for visualizing the CFG.
 *
 * @param namer provides a mapping from CFG objects to identifiers in
 *              generated dot source.
 */
private <N> void formatNodeText(Body body, DotGraph canvas, DotNamer<N> namer) {
    LabeledUnitPrinter printer = null;
    if (body != null) {
        printer = new BriefUnitPrinter(body);
        printer.noIndent();
    }
    for (Iterator<N> nodesIt = namer.keySet().iterator(); nodesIt.hasNext(); ) {
        N node = nodesIt.next();
        DotGraphNode dotnode = canvas.getNode(namer.getName(node));
        String nodeLabel = null;
        if (node instanceof DominatorNode) {
            node = ((DominatorNode<N>) node).getGode();
        }
        if (printer == null) {
            nodeLabel = node.toString();
        } else {
            if (node instanceof Unit) {
                ((Unit) node).toString(printer);
                String targetLabel = printer.labels().get(node);
                if (targetLabel == null) {
                    nodeLabel = printer.toString();
                } else {
                    nodeLabel = targetLabel + ": " + printer.toString();
                }
            } else if (node instanceof Block) {
                Iterator<Unit> units = ((Block) node).iterator();
                StringBuffer buffer = new StringBuffer();
                while (units.hasNext()) {
                    Unit unit = units.next();
                    String targetLabel = (String) printer.labels().get(unit);
                    if (targetLabel != null) {
                        buffer.append(targetLabel).append(":\\n");
                    }
                    unit.toString(printer);
                    buffer.append(printer.toString()).append("\\l");
                }
                nodeLabel = buffer.toString();
            } else {
                nodeLabel = node.toString();
            }
        }
        dotnode.setLabel(nodeLabel);
    }
}
Also used : DominatorNode(soot.toolkits.graph.DominatorNode) Block(soot.toolkits.graph.Block) DotGraphNode(soot.util.dot.DotGraphNode)

Example 10 with Block

use of soot.toolkits.graph.Block 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

Block (soot.toolkits.graph.Block)11 Unit (soot.Unit)5 LinkedList (java.util.LinkedList)3 DominatorNode (soot.toolkits.graph.DominatorNode)3 HashSet (java.util.HashSet)2 ArrayList (java.util.ArrayList)1 HashMap (java.util.HashMap)1 Hashtable (java.util.Hashtable)1 Iterator (java.util.Iterator)1 List (java.util.List)1 Set (java.util.Set)1 Body (soot.Body)1 Local (soot.Local)1 Trap (soot.Trap)1 UnitBox (soot.UnitBox)1 JasminAttribute (soot.tagkit.JasminAttribute)1 LineNumberTag (soot.tagkit.LineNumberTag)1 Tag (soot.tagkit.Tag)1 BlockGraph (soot.toolkits.graph.BlockGraph)1 BriefBlockGraph (soot.toolkits.graph.BriefBlockGraph)1