Search in sources :

Example 1 with BytecodeArray

use of com.android.dx.cf.code.BytecodeArray 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 2 with BytecodeArray

use of com.android.dx.cf.code.BytecodeArray in project J2ME-Loader by nikita36078.

the class StdAttributeFactory method code.

/**
 * Parses a {@code Code} attribute.
 */
private Attribute code(DirectClassFile cf, int offset, int length, ParseObserver observer) {
    if (length < 12) {
        return throwSeverelyTruncated();
    }
    ByteArray bytes = cf.getBytes();
    ConstantPool pool = cf.getConstantPool();
    // u2 max_stack
    int maxStack = bytes.getUnsignedShort(offset);
    // u2 max_locals
    int maxLocals = bytes.getUnsignedShort(offset + 2);
    // u4 code_length
    int codeLength = bytes.getInt(offset + 4);
    int origOffset = offset;
    if (observer != null) {
        observer.parsed(bytes, offset, 2, "max_stack: " + Hex.u2(maxStack));
        observer.parsed(bytes, offset + 2, 2, "max_locals: " + Hex.u2(maxLocals));
        observer.parsed(bytes, offset + 4, 4, "code_length: " + Hex.u4(codeLength));
    }
    offset += 8;
    length -= 8;
    if (length < (codeLength + 4)) {
        return throwTruncated();
    }
    int codeOffset = offset;
    offset += codeLength;
    length -= codeLength;
    BytecodeArray code = new BytecodeArray(bytes.slice(codeOffset, codeOffset + codeLength), pool);
    if (observer != null) {
        code.forEach(new CodeObserver(code.getBytes(), observer));
    }
    // u2 exception_table_length
    int exceptionTableLength = bytes.getUnsignedShort(offset);
    ByteCatchList catches = (exceptionTableLength == 0) ? ByteCatchList.EMPTY : new ByteCatchList(exceptionTableLength);
    if (observer != null) {
        observer.parsed(bytes, offset, 2, "exception_table_length: " + Hex.u2(exceptionTableLength));
    }
    offset += 2;
    length -= 2;
    if (length < (exceptionTableLength * 8 + 2)) {
        return throwTruncated();
    }
    for (int i = 0; i < exceptionTableLength; i++) {
        if (observer != null) {
            observer.changeIndent(1);
        }
        int startPc = bytes.getUnsignedShort(offset);
        int endPc = bytes.getUnsignedShort(offset + 2);
        int handlerPc = bytes.getUnsignedShort(offset + 4);
        int catchTypeIdx = bytes.getUnsignedShort(offset + 6);
        CstType catchType = (CstType) pool.get0Ok(catchTypeIdx);
        catches.set(i, startPc, endPc, handlerPc, catchType);
        if (observer != null) {
            observer.parsed(bytes, offset, 8, Hex.u2(startPc) + ".." + Hex.u2(endPc) + " -> " + Hex.u2(handlerPc) + " " + ((catchType == null) ? "<any>" : catchType.toHuman()));
        }
        offset += 8;
        length -= 8;
        if (observer != null) {
            observer.changeIndent(-1);
        }
    }
    catches.setImmutable();
    AttributeListParser parser = new AttributeListParser(cf, CTX_CODE, offset, this);
    parser.setObserver(observer);
    StdAttributeList attributes = parser.getList();
    attributes.setImmutable();
    int attributeByteCount = parser.getEndOffset() - offset;
    if (attributeByteCount != length) {
        return throwBadLength(attributeByteCount + (offset - origOffset));
    }
    return new AttCode(maxStack, maxLocals, code, catches, attributes);
}
Also used : BytecodeArray(com.android.dx.cf.code.BytecodeArray) StdAttributeList(com.android.dx.cf.iface.StdAttributeList) ByteCatchList(com.android.dx.cf.code.ByteCatchList) ConstantPool(com.android.dx.rop.cst.ConstantPool) CstType(com.android.dx.rop.cst.CstType) AttCode(com.android.dx.cf.attrib.AttCode) ByteArray(com.android.dx.util.ByteArray)

Example 3 with BytecodeArray

use of com.android.dx.cf.code.BytecodeArray in project buck by facebook.

the class StdAttributeFactory method code.

/**
     * Parses a {@code Code} attribute.
     */
private Attribute code(DirectClassFile cf, int offset, int length, ParseObserver observer) {
    if (length < 12) {
        return throwSeverelyTruncated();
    }
    ByteArray bytes = cf.getBytes();
    ConstantPool pool = cf.getConstantPool();
    // u2 max_stack
    int maxStack = bytes.getUnsignedShort(offset);
    // u2 max_locals
    int maxLocals = bytes.getUnsignedShort(offset + 2);
    // u4 code_length
    int codeLength = bytes.getInt(offset + 4);
    int origOffset = offset;
    if (observer != null) {
        observer.parsed(bytes, offset, 2, "max_stack: " + Hex.u2(maxStack));
        observer.parsed(bytes, offset + 2, 2, "max_locals: " + Hex.u2(maxLocals));
        observer.parsed(bytes, offset + 4, 4, "code_length: " + Hex.u4(codeLength));
    }
    offset += 8;
    length -= 8;
    if (length < (codeLength + 4)) {
        return throwTruncated();
    }
    int codeOffset = offset;
    offset += codeLength;
    length -= codeLength;
    BytecodeArray code = new BytecodeArray(bytes.slice(codeOffset, codeOffset + codeLength), pool);
    if (observer != null) {
        code.forEach(new CodeObserver(code.getBytes(), observer));
    }
    // u2 exception_table_length
    int exceptionTableLength = bytes.getUnsignedShort(offset);
    ByteCatchList catches = (exceptionTableLength == 0) ? ByteCatchList.EMPTY : new ByteCatchList(exceptionTableLength);
    if (observer != null) {
        observer.parsed(bytes, offset, 2, "exception_table_length: " + Hex.u2(exceptionTableLength));
    }
    offset += 2;
    length -= 2;
    if (length < (exceptionTableLength * 8 + 2)) {
        return throwTruncated();
    }
    for (int i = 0; i < exceptionTableLength; i++) {
        if (observer != null) {
            observer.changeIndent(1);
        }
        int startPc = bytes.getUnsignedShort(offset);
        int endPc = bytes.getUnsignedShort(offset + 2);
        int handlerPc = bytes.getUnsignedShort(offset + 4);
        int catchTypeIdx = bytes.getUnsignedShort(offset + 6);
        CstType catchType = (CstType) pool.get0Ok(catchTypeIdx);
        catches.set(i, startPc, endPc, handlerPc, catchType);
        if (observer != null) {
            observer.parsed(bytes, offset, 8, Hex.u2(startPc) + ".." + Hex.u2(endPc) + " -> " + Hex.u2(handlerPc) + " " + ((catchType == null) ? "<any>" : catchType.toHuman()));
        }
        offset += 8;
        length -= 8;
        if (observer != null) {
            observer.changeIndent(-1);
        }
    }
    catches.setImmutable();
    AttributeListParser parser = new AttributeListParser(cf, CTX_CODE, offset, this);
    parser.setObserver(observer);
    StdAttributeList attributes = parser.getList();
    attributes.setImmutable();
    int attributeByteCount = parser.getEndOffset() - offset;
    if (attributeByteCount != length) {
        return throwBadLength(attributeByteCount + (offset - origOffset));
    }
    return new AttCode(maxStack, maxLocals, code, catches, attributes);
}
Also used : BytecodeArray(com.android.dx.cf.code.BytecodeArray) StdAttributeList(com.android.dx.cf.iface.StdAttributeList) ByteCatchList(com.android.dx.cf.code.ByteCatchList) ConstantPool(com.android.dx.rop.cst.ConstantPool) CstType(com.android.dx.rop.cst.CstType) AttCode(com.android.dx.cf.attrib.AttCode) ByteArray(com.android.dx.util.ByteArray)

Example 4 with BytecodeArray

use of com.android.dx.cf.code.BytecodeArray in project buck by facebook.

the class BlockDumper method ropDump.

/**
     * Does a registerizing dump.
     *
     * @param meth {@code non-null;} method data to dump
     */
private void ropDump(ConcreteMethod meth) {
    TranslationAdvice advice = DexTranslationAdvice.THE_ONE;
    BytecodeArray code = meth.getCode();
    ByteArray bytes = code.getBytes();
    RopMethod rmeth = Ropper.convert(meth, advice, classFile.getMethods());
    StringBuffer sb = new StringBuffer(2000);
    if (optimize) {
        boolean isStatic = AccessFlags.isStatic(meth.getAccessFlags());
        int paramWidth = computeParamWidth(meth, isStatic);
        rmeth = Optimizer.optimize(rmeth, paramWidth, isStatic, true, advice);
    }
    BasicBlockList blocks = rmeth.getBlocks();
    int[] order = blocks.getLabelsInOrder();
    sb.append("first " + Hex.u2(rmeth.getFirstLabel()) + "\n");
    for (int label : order) {
        BasicBlock bb = blocks.get(blocks.indexOfLabel(label));
        sb.append("block ");
        sb.append(Hex.u2(label));
        sb.append("\n");
        IntList preds = rmeth.labelToPredecessors(label);
        int psz = preds.size();
        for (int i = 0; i < psz; i++) {
            sb.append("  pred ");
            sb.append(Hex.u2(preds.get(i)));
            sb.append("\n");
        }
        InsnList il = bb.getInsns();
        int ilsz = il.size();
        for (int i = 0; i < ilsz; i++) {
            Insn one = il.get(i);
            sb.append("  ");
            sb.append(il.get(i).toHuman());
            sb.append("\n");
        }
        IntList successors = bb.getSuccessors();
        int ssz = successors.size();
        if (ssz == 0) {
            sb.append("  returns\n");
        } else {
            int primary = bb.getPrimarySuccessor();
            for (int i = 0; i < ssz; i++) {
                int succ = successors.get(i);
                sb.append("  next ");
                sb.append(Hex.u2(succ));
                if ((ssz != 1) && (succ == primary)) {
                    sb.append(" *");
                }
                sb.append("\n");
            }
        }
    }
    suppressDump = false;
    setAt(bytes, 0);
    parsed(bytes, 0, bytes.size(), sb.toString());
    suppressDump = true;
}
Also used : BytecodeArray(com.android.dx.cf.code.BytecodeArray) Insn(com.android.dx.rop.code.Insn) RopMethod(com.android.dx.rop.code.RopMethod) BasicBlock(com.android.dx.rop.code.BasicBlock) DexTranslationAdvice(com.android.dx.rop.code.DexTranslationAdvice) TranslationAdvice(com.android.dx.rop.code.TranslationAdvice) InsnList(com.android.dx.rop.code.InsnList) IntList(com.android.dx.util.IntList) ByteArray(com.android.dx.util.ByteArray) BasicBlockList(com.android.dx.rop.code.BasicBlockList)

Aggregations

BytecodeArray (com.android.dx.cf.code.BytecodeArray)4 ByteArray (com.android.dx.util.ByteArray)4 ByteCatchList (com.android.dx.cf.code.ByteCatchList)3 CstType (com.android.dx.rop.cst.CstType)3 AttCode (com.android.dx.cf.attrib.AttCode)2 StdAttributeList (com.android.dx.cf.iface.StdAttributeList)2 ConstantPool (com.android.dx.rop.cst.ConstantPool)2 IntList (com.android.dx.util.IntList)2 ByteBlock (com.android.dx.cf.code.ByteBlock)1 ByteBlockList (com.android.dx.cf.code.ByteBlockList)1 CodeObserver (com.android.dx.cf.direct.CodeObserver)1 BasicBlock (com.android.dx.rop.code.BasicBlock)1 BasicBlockList (com.android.dx.rop.code.BasicBlockList)1 DexTranslationAdvice (com.android.dx.rop.code.DexTranslationAdvice)1 Insn (com.android.dx.rop.code.Insn)1 InsnList (com.android.dx.rop.code.InsnList)1 RopMethod (com.android.dx.rop.code.RopMethod)1 TranslationAdvice (com.android.dx.rop.code.TranslationAdvice)1