Search in sources :

Example 1 with BasicBlockList

use of com.android.dx.rop.code.BasicBlockList in project buck by facebook.

the class StdCatchBuilder method build.

/**
     * Builds and returns the catch table for a given method.
     *
     * @param method {@code non-null;} method to build the list for
     * @param order {@code non-null;} block output order
     * @param addresses {@code non-null;} address objects for each block
     * @return {@code non-null;} the constructed table
     */
public static CatchTable build(RopMethod method, int[] order, BlockAddresses addresses) {
    int len = order.length;
    BasicBlockList blocks = method.getBlocks();
    ArrayList<CatchTable.Entry> resultList = new ArrayList<CatchTable.Entry>(len);
    CatchHandlerList currentHandlers = CatchHandlerList.EMPTY;
    BasicBlock currentStartBlock = null;
    BasicBlock currentEndBlock = null;
    for (int i = 0; i < len; i++) {
        BasicBlock block = blocks.labelToBlock(order[i]);
        if (!block.canThrow()) {
            /*
                 * There is no need to concern ourselves with the
                 * placement of blocks that can't throw with respect
                 * to the blocks that *can* throw.
                 */
            continue;
        }
        CatchHandlerList handlers = handlersFor(block, addresses);
        if (currentHandlers.size() == 0) {
            // This is the start of a new catch range.
            currentStartBlock = block;
            currentEndBlock = block;
            currentHandlers = handlers;
            continue;
        }
        if (currentHandlers.equals(handlers) && rangeIsValid(currentStartBlock, block, addresses)) {
            /*
                 * The block we are looking at now has the same handlers
                 * as the block that started the currently open catch
                 * range, and adding it to the currently open range won't
                 * cause it to be too long.
                 */
            currentEndBlock = block;
            continue;
        }
        /*
             * The block we are looking at now has incompatible handlers,
             * so we need to finish off the last entry and start a new
             * one. Note: We only emit an entry if it has associated handlers.
             */
        if (currentHandlers.size() != 0) {
            CatchTable.Entry entry = makeEntry(currentStartBlock, currentEndBlock, currentHandlers, addresses);
            resultList.add(entry);
        }
        currentStartBlock = block;
        currentEndBlock = block;
        currentHandlers = handlers;
    }
    if (currentHandlers.size() != 0) {
        // Emit an entry for the range that was left hanging.
        CatchTable.Entry entry = makeEntry(currentStartBlock, currentEndBlock, currentHandlers, addresses);
        resultList.add(entry);
    }
    // Construct the final result.
    int resultSz = resultList.size();
    if (resultSz == 0) {
        return CatchTable.EMPTY;
    }
    CatchTable result = new CatchTable(resultSz);
    for (int i = 0; i < resultSz; i++) {
        result.set(i, resultList.get(i));
    }
    result.setImmutable();
    return result;
}
Also used : ArrayList(java.util.ArrayList) BasicBlock(com.android.dx.rop.code.BasicBlock) BasicBlockList(com.android.dx.rop.code.BasicBlockList)

Example 2 with BasicBlockList

use of com.android.dx.rop.code.BasicBlockList in project buck by facebook.

the class BlockAddresses method setupArrays.

/**
     * Sets up the address arrays.
     */
private void setupArrays(RopMethod method) {
    BasicBlockList blocks = method.getBlocks();
    int sz = blocks.size();
    for (int i = 0; i < sz; i++) {
        BasicBlock one = blocks.get(i);
        int label = one.getLabel();
        Insn insn = one.getInsns().get(0);
        starts[label] = new CodeAddress(insn.getPosition());
        SourcePosition pos = one.getLastInsn().getPosition();
        lasts[label] = new CodeAddress(pos);
        ends[label] = new CodeAddress(pos);
    }
}
Also used : Insn(com.android.dx.rop.code.Insn) SourcePosition(com.android.dx.rop.code.SourcePosition) BasicBlock(com.android.dx.rop.code.BasicBlock) BasicBlockList(com.android.dx.rop.code.BasicBlockList)

Example 3 with BasicBlockList

use of com.android.dx.rop.code.BasicBlockList in project buck by facebook.

the class DotDumper method endParsingMember.

public void endParsingMember(ByteArray bytes, int offset, String name, String descriptor, Member member) {
    if (!(member instanceof Method)) {
        return;
    }
    if (!shouldDumpMethod(name)) {
        return;
    }
    ConcreteMethod meth = new ConcreteMethod((Method) member, classFile, true, true);
    TranslationAdvice advice = DexTranslationAdvice.THE_ONE;
    RopMethod rmeth = Ropper.convert(meth, advice, classFile.getMethods());
    if (optimize) {
        boolean isStatic = AccessFlags.isStatic(meth.getAccessFlags());
        rmeth = Optimizer.optimize(rmeth, BaseDumper.computeParamWidth(meth, isStatic), isStatic, true, advice);
    }
    System.out.println("digraph " + name + "{");
    System.out.println("\tfirst -> n" + Hex.u2(rmeth.getFirstLabel()) + ";");
    BasicBlockList blocks = rmeth.getBlocks();
    int sz = blocks.size();
    for (int i = 0; i < sz; i++) {
        BasicBlock bb = blocks.get(i);
        int label = bb.getLabel();
        IntList successors = bb.getSuccessors();
        if (successors.size() == 0) {
            System.out.println("\tn" + Hex.u2(label) + " -> returns;");
        } else if (successors.size() == 1) {
            System.out.println("\tn" + Hex.u2(label) + " -> n" + Hex.u2(successors.get(0)) + ";");
        } else {
            System.out.print("\tn" + Hex.u2(label) + " -> {");
            for (int j = 0; j < successors.size(); j++) {
                int successor = successors.get(j);
                if (successor != bb.getPrimarySuccessor()) {
                    System.out.print(" n" + Hex.u2(successor) + " ");
                }
            }
            System.out.println("};");
            System.out.println("\tn" + Hex.u2(label) + " -> n" + Hex.u2(bb.getPrimarySuccessor()) + " [label=\"primary\"];");
        }
    }
    System.out.println("}");
}
Also used : RopMethod(com.android.dx.rop.code.RopMethod) ConcreteMethod(com.android.dx.cf.code.ConcreteMethod) BasicBlock(com.android.dx.rop.code.BasicBlock) DexTranslationAdvice(com.android.dx.rop.code.DexTranslationAdvice) TranslationAdvice(com.android.dx.rop.code.TranslationAdvice) ConcreteMethod(com.android.dx.cf.code.ConcreteMethod) RopMethod(com.android.dx.rop.code.RopMethod) Method(com.android.dx.cf.iface.Method) BasicBlockList(com.android.dx.rop.code.BasicBlockList) IntList(com.android.dx.util.IntList)

Example 4 with BasicBlockList

use of com.android.dx.rop.code.BasicBlockList in project buck by facebook.

the class Ropper method getRopMethod.

/**
     * Extracts the resulting {@link RopMethod} from the instance.
     *
     * @return {@code non-null;} the method object
     */
private RopMethod getRopMethod() {
    // Construct the final list of blocks.
    int sz = result.size();
    BasicBlockList bbl = new BasicBlockList(sz);
    for (int i = 0; i < sz; i++) {
        bbl.set(i, result.get(i));
    }
    bbl.setImmutable();
    /*
         * Note: The parameter assignment block is always the first
         * that should be executed, hence the second argument to the
         * constructor.
         */
    return new RopMethod(bbl, getSpecialLabel(PARAM_ASSIGNMENT));
}
Also used : RopMethod(com.android.dx.rop.code.RopMethod) BasicBlockList(com.android.dx.rop.code.BasicBlockList)

Example 5 with BasicBlockList

use of com.android.dx.rop.code.BasicBlockList in project buck by facebook.

the class SsaToRop method convertBasicBlocks.

/**
     * @return rop-form basic block list
     */
private BasicBlockList convertBasicBlocks() {
    ArrayList<SsaBasicBlock> blocks = ssaMeth.getBlocks();
    // Exit block may be null.
    SsaBasicBlock exitBlock = ssaMeth.getExitBlock();
    ssaMeth.computeReachability();
    int ropBlockCount = ssaMeth.getCountReachableBlocks();
    // Don't count the exit block, if it exists and is reachable.
    ropBlockCount -= (exitBlock != null && exitBlock.isReachable()) ? 1 : 0;
    BasicBlockList result = new BasicBlockList(ropBlockCount);
    // Convert all the reachable blocks except the exit block.
    int ropBlockIndex = 0;
    for (SsaBasicBlock b : blocks) {
        if (b.isReachable() && b != exitBlock) {
            result.set(ropBlockIndex++, convertBasicBlock(b));
        }
    }
    // The exit block, which is discarded, must do nothing.
    if (exitBlock != null && exitBlock.getInsns().size() != 0) {
        throw new RuntimeException("Exit block must have no insns when leaving SSA form");
    }
    return result;
}
Also used : SsaBasicBlock(com.android.dx.ssa.SsaBasicBlock) BasicBlockList(com.android.dx.rop.code.BasicBlockList)

Aggregations

BasicBlockList (com.android.dx.rop.code.BasicBlockList)22 BasicBlock (com.android.dx.rop.code.BasicBlock)14 RopMethod (com.android.dx.rop.code.RopMethod)4 TypeList (com.android.dx.rop.type.TypeList)4 IntList (com.android.dx.util.IntList)4 Insn (com.android.dx.rop.code.Insn)3 InsnList (com.android.dx.rop.code.InsnList)3 DexTranslationAdvice (com.android.dx.rop.code.DexTranslationAdvice)2 SourcePosition (com.android.dx.rop.code.SourcePosition)2 TranslationAdvice (com.android.dx.rop.code.TranslationAdvice)2 CstType (com.android.dx.rop.cst.CstType)2 Type (com.android.dx.rop.type.Type)2 SsaBasicBlock (com.android.dx.ssa.SsaBasicBlock)2 ArrayList (java.util.ArrayList)2 HashSet (java.util.HashSet)2 BytecodeArray (com.android.dx.cf.code.BytecodeArray)1 ConcreteMethod (com.android.dx.cf.code.ConcreteMethod)1 Method (com.android.dx.cf.iface.Method)1 ByteArray (com.android.dx.util.ByteArray)1