Search in sources :

Example 1 with IntList

use of com.android.dx.util.IntList in project buck by facebook.

the class BasicBlocker method getBlockList.

/**
     * Extracts the list of basic blocks from the bit sets.
     *
     * @return {@code non-null;} the list of basic blocks
     */
private ByteBlockList getBlockList() {
    BytecodeArray bytes = method.getCode();
    ByteBlock[] bbs = new ByteBlock[bytes.size()];
    int count = 0;
    for (int at = 0, next; ; /*at*/
    at = next) {
        next = Bits.findFirst(blockSet, at + 1);
        if (next < 0) {
            break;
        }
        if (Bits.get(liveSet, at)) {
            /*
                 * Search backward for the branch or throwing
                 * instruction at the end of this block, if any. If
                 * there isn't any, then "next" is the sole target.
                 */
            IntList targets = null;
            int targetsAt = -1;
            ByteCatchList blockCatches;
            for (int i = next - 1; i >= at; i--) {
                targets = targetLists[i];
                if (targets != null) {
                    targetsAt = i;
                    break;
                }
            }
            if (targets == null) {
                targets = IntList.makeImmutable(next);
                blockCatches = ByteCatchList.EMPTY;
            } else {
                blockCatches = catchLists[targetsAt];
                if (blockCatches == null) {
                    blockCatches = ByteCatchList.EMPTY;
                }
            }
            bbs[count] = new ByteBlock(at, at, next, targets, blockCatches);
            count++;
        }
    }
    ByteBlockList result = new ByteBlockList(count);
    for (int i = 0; i < count; i++) {
        result.set(i, bbs[i]);
    }
    return result;
}
Also used : IntList(com.android.dx.util.IntList)

Example 2 with IntList

use of com.android.dx.util.IntList in project buck by facebook.

the class ByteCatchList method toTargetList.

/**
     * Returns a target list corresponding to this instance. The result
     * is a list of all the exception handler addresses, with the given
     * {@code noException} address appended if appropriate. The
     * result is automatically made immutable.
     *
     * @param noException {@code >= -1;} the no-exception address to append, or
     * {@code -1} not to append anything
     * @return {@code non-null;} list of exception targets, with
     * {@code noException} appended if necessary
     */
public IntList toTargetList(int noException) {
    if (noException < -1) {
        throw new IllegalArgumentException("noException < -1");
    }
    boolean hasDefault = (noException >= 0);
    int sz = size();
    if (sz == 0) {
        if (hasDefault) {
            /*
                 * The list is empty, but there is a no-exception
                 * address; so, the result is just that address.
                 */
            return IntList.makeImmutable(noException);
        }
        /*
             * The list is empty and there isn't even a no-exception
             * address.
             */
        return IntList.EMPTY;
    }
    IntList result = new IntList(sz + (hasDefault ? 1 : 0));
    for (int i = 0; i < sz; i++) {
        result.add(get(i).getHandlerPc());
    }
    if (hasDefault) {
        result.add(noException);
    }
    result.setImmutable();
    return result;
}
Also used : IntList(com.android.dx.util.IntList)

Example 3 with IntList

use of com.android.dx.util.IntList in project buck by facebook.

the class BlockDumper method regularDump.

/**
     * Does a regular basic block dump.
     *
     * @param meth {@code non-null;} method data to dump
     */
private void regularDump(ConcreteMethod meth) {
    BytecodeArray code = meth.getCode();
    ByteArray bytes = code.getBytes();
    ByteBlockList list = BasicBlocker.identifyBlocks(meth);
    int sz = list.size();
    CodeObserver codeObserver = new CodeObserver(bytes, BlockDumper.this);
    // Reset the dump cursor to the start of the bytecode.
    setAt(bytes, 0);
    suppressDump = false;
    int byteAt = 0;
    for (int i = 0; i < sz; i++) {
        ByteBlock bb = list.get(i);
        int start = bb.getStart();
        int end = bb.getEnd();
        if (byteAt < start) {
            parsed(bytes, byteAt, start - byteAt, "dead code " + Hex.u2(byteAt) + ".." + Hex.u2(start));
        }
        parsed(bytes, start, 0, "block " + Hex.u2(bb.getLabel()) + ": " + Hex.u2(start) + ".." + Hex.u2(end));
        changeIndent(1);
        int len;
        for (int j = start; j < end; j += len) {
            len = code.parseInstruction(j, codeObserver);
            codeObserver.setPreviousOffset(j);
        }
        IntList successors = bb.getSuccessors();
        int ssz = successors.size();
        if (ssz == 0) {
            parsed(bytes, end, 0, "returns");
        } else {
            for (int j = 0; j < ssz; j++) {
                int succ = successors.get(j);
                parsed(bytes, end, 0, "next " + Hex.u2(succ));
            }
        }
        ByteCatchList catches = bb.getCatches();
        int csz = catches.size();
        for (int j = 0; j < csz; j++) {
            ByteCatchList.Item one = catches.get(j);
            CstType exceptionClass = one.getExceptionClass();
            parsed(bytes, end, 0, "catch " + ((exceptionClass == CstType.OBJECT) ? "<any>" : exceptionClass.toHuman()) + " -> " + Hex.u2(one.getHandlerPc()));
        }
        changeIndent(-1);
        byteAt = end;
    }
    int end = bytes.size();
    if (byteAt < end) {
        parsed(bytes, byteAt, end - byteAt, "dead code " + Hex.u2(byteAt) + ".." + Hex.u2(end));
    }
    suppressDump = true;
}
Also used : BytecodeArray(com.android.dx.cf.code.BytecodeArray) ByteCatchList(com.android.dx.cf.code.ByteCatchList) ByteBlock(com.android.dx.cf.code.ByteBlock) CstType(com.android.dx.rop.cst.CstType) ByteArray(com.android.dx.util.ByteArray) CodeObserver(com.android.dx.cf.direct.CodeObserver) ByteBlockList(com.android.dx.cf.code.ByteBlockList) IntList(com.android.dx.util.IntList)

Example 4 with IntList

use of com.android.dx.util.IntList 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 5 with IntList

use of com.android.dx.util.IntList in project buck by facebook.

the class Ropper method isSubroutineCaller.

/**
     * Checks to see if the basic block is a subroutine caller block.
     *
     * @param bb {@code non-null;} the basic block in question
     * @return true if this block calls a subroutine
     */
private boolean isSubroutineCaller(BasicBlock bb) {
    IntList successors = bb.getSuccessors();
    if (successors.size() < 2)
        return false;
    int subLabel = successors.get(1);
    return (subLabel < subroutines.length) && (subroutines[subLabel] != null);
}
Also used : IntList(com.android.dx.util.IntList)

Aggregations

IntList (com.android.dx.util.IntList)57 BasicBlock (com.android.dx.rop.code.BasicBlock)21 CstType (com.android.dx.rop.cst.CstType)7 Insn (com.android.dx.rop.code.Insn)5 RopMethod (com.android.dx.rop.code.RopMethod)5 BasicBlockList (com.android.dx.rop.code.BasicBlockList)4 InsnList (com.android.dx.rop.code.InsnList)4 PlainCstInsn (com.android.dx.rop.code.PlainCstInsn)4 PlainInsn (com.android.dx.rop.code.PlainInsn)4 RegisterSpec (com.android.dx.rop.code.RegisterSpec)4 SourcePosition (com.android.dx.rop.code.SourcePosition)4 ThrowingCstInsn (com.android.dx.rop.code.ThrowingCstInsn)4 ThrowingInsn (com.android.dx.rop.code.ThrowingInsn)4 Type (com.android.dx.rop.type.Type)4 TypeList (com.android.dx.rop.type.TypeList)4 DexTranslationAdvice (com.android.dx.rop.code.DexTranslationAdvice)3 TranslationAdvice (com.android.dx.rop.code.TranslationAdvice)3 SsaBasicBlock (com.android.dx.ssa.SsaBasicBlock)3 ArrayList (java.util.ArrayList)3 BitSet (java.util.BitSet)3