Search in sources :

Example 1 with BytecodeArray

use of com.taobao.android.dx.cf.code.BytecodeArray in project atlas by alibaba.

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.taobao.android.dx.cf.code.BytecodeArray) ByteCatchList(com.taobao.android.dx.cf.code.ByteCatchList) ByteBlock(com.taobao.android.dx.cf.code.ByteBlock) CstType(com.taobao.android.dx.rop.cst.CstType) ByteArray(com.taobao.android.dx.util.ByteArray) CodeObserver(com.taobao.android.dx.cf.direct.CodeObserver) ByteBlockList(com.taobao.android.dx.cf.code.ByteBlockList) IntList(com.taobao.android.dx.util.IntList)

Example 2 with BytecodeArray

use of com.taobao.android.dx.cf.code.BytecodeArray in project atlas by alibaba.

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.taobao.android.dx.cf.code.BytecodeArray) Insn(com.taobao.android.dx.rop.code.Insn) RopMethod(com.taobao.android.dx.rop.code.RopMethod) BasicBlock(com.taobao.android.dx.rop.code.BasicBlock) TranslationAdvice(com.taobao.android.dx.rop.code.TranslationAdvice) DexTranslationAdvice(com.taobao.android.dx.rop.code.DexTranslationAdvice) InsnList(com.taobao.android.dx.rop.code.InsnList) IntList(com.taobao.android.dx.util.IntList) ByteArray(com.taobao.android.dx.util.ByteArray) BasicBlockList(com.taobao.android.dx.rop.code.BasicBlockList)

Example 3 with BytecodeArray

use of com.taobao.android.dx.cf.code.BytecodeArray in project atlas by alibaba.

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.taobao.android.dx.cf.code.BytecodeArray) StdAttributeList(com.taobao.android.dx.cf.iface.StdAttributeList) ByteCatchList(com.taobao.android.dx.cf.code.ByteCatchList) ConstantPool(com.taobao.android.dx.rop.cst.ConstantPool) CstType(com.taobao.android.dx.rop.cst.CstType) AttCode(com.taobao.android.dx.cf.attrib.AttCode) ByteArray(com.taobao.android.dx.util.ByteArray)

Aggregations

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