Search in sources :

Example 11 with CstType

use of com.android.dx.rop.cst.CstType in project buck by facebook.

the class CfTranslator method processFields.

/**
     * Processes the fields of the given class.
     *
     * @param cf {@code non-null;} class being translated
     * @param out {@code non-null;} output class
     * @param dexFile {@code non-null;} dex output
     */
private static void processFields(DirectClassFile cf, ClassDefItem out, DexFile dexFile) {
    CstType thisClass = cf.getThisClass();
    FieldList fields = cf.getFields();
    int sz = fields.size();
    for (int i = 0; i < sz; i++) {
        Field one = fields.get(i);
        try {
            CstFieldRef field = new CstFieldRef(thisClass, one.getNat());
            int accessFlags = one.getAccessFlags();
            if (AccessFlags.isStatic(accessFlags)) {
                TypedConstant constVal = one.getConstantValue();
                EncodedField fi = new EncodedField(field, accessFlags);
                if (constVal != null) {
                    constVal = coerceConstant(constVal, field.getType());
                }
                out.addStaticField(fi, constVal);
            } else {
                EncodedField fi = new EncodedField(field, accessFlags);
                out.addInstanceField(fi);
            }
            Annotations annotations = AttributeTranslator.getAnnotations(one.getAttributes());
            if (annotations.size() != 0) {
                out.addFieldAnnotations(field, annotations, dexFile);
            }
            dexFile.getFieldIds().intern(field);
        } catch (RuntimeException ex) {
            String msg = "...while processing " + one.getName().toHuman() + " " + one.getDescriptor().toHuman();
            throw ExceptionWithContext.withContext(ex, msg);
        }
    }
}
Also used : Field(com.android.dx.cf.iface.Field) EncodedField(com.android.dx.dex.file.EncodedField) Annotations(com.android.dx.rop.annotation.Annotations) TypedConstant(com.android.dx.rop.cst.TypedConstant) CstType(com.android.dx.rop.cst.CstType) CstFieldRef(com.android.dx.rop.cst.CstFieldRef) EncodedField(com.android.dx.dex.file.EncodedField) CstString(com.android.dx.rop.cst.CstString) FieldList(com.android.dx.cf.iface.FieldList)

Example 12 with CstType

use of com.android.dx.rop.cst.CstType 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 13 with CstType

use of com.android.dx.rop.cst.CstType in project buck by facebook.

the class StdAttributeFactory method enclosingMethod.

/**
     * Parses an {@code EnclosingMethod} attribute.
     */
private Attribute enclosingMethod(DirectClassFile cf, int offset, int length, ParseObserver observer) {
    if (length != 4) {
        throwBadLength(4);
    }
    ByteArray bytes = cf.getBytes();
    ConstantPool pool = cf.getConstantPool();
    int idx = bytes.getUnsignedShort(offset);
    CstType type = (CstType) pool.get(idx);
    idx = bytes.getUnsignedShort(offset + 2);
    CstNat method = (CstNat) pool.get0Ok(idx);
    Attribute result = new AttEnclosingMethod(type, method);
    if (observer != null) {
        observer.parsed(bytes, offset, 2, "class: " + type);
        observer.parsed(bytes, offset + 2, 2, "method: " + DirectClassFile.stringOrNone(method));
    }
    return result;
}
Also used : CstNat(com.android.dx.rop.cst.CstNat) AttEnclosingMethod(com.android.dx.cf.attrib.AttEnclosingMethod) Attribute(com.android.dx.cf.iface.Attribute) ConstantPool(com.android.dx.rop.cst.ConstantPool) CstType(com.android.dx.rop.cst.CstType) ByteArray(com.android.dx.util.ByteArray)

Example 14 with CstType

use of com.android.dx.rop.cst.CstType in project buck by facebook.

the class Main method computeReferencedResources.

private void computeReferencedResources() {
    for (Item genericItem : outputDex.getFieldIds().items()) {
        FieldIdItem item = (FieldIdItem) genericItem;
        CstType fieldClass = item.getDefiningClass();
        CstString fieldName = item.getRef().getNat().getName();
        if (fieldClass.getClassType().getDescriptor().contains("/R$")) {
            // Add the packageName of the class for better accuracy.
            resourceNames.add(fieldClass.getPackageName() + "." + fieldName.getString());
        }
    }
}
Also used : Item(com.android.dx.dex.file.Item) FieldIdItem(com.android.dx.dex.file.FieldIdItem) ClassDefItem(com.android.dx.dex.file.ClassDefItem) FieldIdItem(com.android.dx.dex.file.FieldIdItem) CstType(com.android.dx.rop.cst.CstType) CstString(com.android.dx.rop.cst.CstString)

Example 15 with CstType

use of com.android.dx.rop.cst.CstType in project buck by facebook.

the class BytecodeArray method parseNewarray.

/**
     * Helper to deal with {@code newarray}.
     *
     * @param offset the offset to the {@code newarray} opcode itself
     * @param visitor {@code non-null;} visitor to use
     * @return instruction length, in bytes
     */
private int parseNewarray(int offset, Visitor visitor) {
    int value = bytes.getUnsignedByte(offset + 1);
    CstType type;
    switch(value) {
        case ByteOps.NEWARRAY_BOOLEAN:
            {
                type = CstType.BOOLEAN_ARRAY;
                break;
            }
        case ByteOps.NEWARRAY_CHAR:
            {
                type = CstType.CHAR_ARRAY;
                break;
            }
        case ByteOps.NEWARRAY_DOUBLE:
            {
                type = CstType.DOUBLE_ARRAY;
                break;
            }
        case ByteOps.NEWARRAY_FLOAT:
            {
                type = CstType.FLOAT_ARRAY;
                break;
            }
        case ByteOps.NEWARRAY_BYTE:
            {
                type = CstType.BYTE_ARRAY;
                break;
            }
        case ByteOps.NEWARRAY_SHORT:
            {
                type = CstType.SHORT_ARRAY;
                break;
            }
        case ByteOps.NEWARRAY_INT:
            {
                type = CstType.INT_ARRAY;
                break;
            }
        case ByteOps.NEWARRAY_LONG:
            {
                type = CstType.LONG_ARRAY;
                break;
            }
        default:
            {
                throw new SimException("bad newarray code " + Hex.u1(value));
            }
    }
    // Revisit the previous bytecode to find out the length of the array
    int previousOffset = visitor.getPreviousOffset();
    ConstantParserVisitor constantVisitor = new ConstantParserVisitor();
    int arrayLength = 0;
    /*
         * For visitors that don't record the previous offset, -1 will be
         * seen here
         */
    if (previousOffset >= 0) {
        parseInstruction(previousOffset, constantVisitor);
        if (constantVisitor.cst instanceof CstInteger && constantVisitor.length + previousOffset == offset) {
            arrayLength = constantVisitor.value;
        }
    }
    /*
         * Try to match the array initialization idiom. For example, if the
         * subsequent code is initializing an int array, we are expecting the
         * following pattern repeatedly:
         *  dup
         *  push index
         *  push value
         *  *astore
         *
         * where the index value will be incrimented sequentially from 0 up.
         */
    int nInit = 0;
    int curOffset = offset + 2;
    int lastOffset = curOffset;
    ArrayList<Constant> initVals = new ArrayList<Constant>();
    if (arrayLength != 0) {
        while (true) {
            boolean punt = false;
            // First, check if the next bytecode is dup.
            int nextByte = bytes.getUnsignedByte(curOffset++);
            if (nextByte != ByteOps.DUP)
                break;
            /*
                 * Next, check if the expected array index is pushed to
                 * the stack.
                 */
            parseInstruction(curOffset, constantVisitor);
            if (constantVisitor.length == 0 || !(constantVisitor.cst instanceof CstInteger) || constantVisitor.value != nInit)
                break;
            // Next, fetch the init value and record it.
            curOffset += constantVisitor.length;
            /*
                 * Next, find out what kind of constant is pushed onto
                 * the stack.
                 */
            parseInstruction(curOffset, constantVisitor);
            if (constantVisitor.length == 0 || !(constantVisitor.cst instanceof CstLiteralBits))
                break;
            curOffset += constantVisitor.length;
            initVals.add(constantVisitor.cst);
            nextByte = bytes.getUnsignedByte(curOffset++);
            // Now, check if the value is stored to the array properly.
            switch(value) {
                case ByteOps.NEWARRAY_BYTE:
                case ByteOps.NEWARRAY_BOOLEAN:
                    {
                        if (nextByte != ByteOps.BASTORE) {
                            punt = true;
                        }
                        break;
                    }
                case ByteOps.NEWARRAY_CHAR:
                    {
                        if (nextByte != ByteOps.CASTORE) {
                            punt = true;
                        }
                        break;
                    }
                case ByteOps.NEWARRAY_DOUBLE:
                    {
                        if (nextByte != ByteOps.DASTORE) {
                            punt = true;
                        }
                        break;
                    }
                case ByteOps.NEWARRAY_FLOAT:
                    {
                        if (nextByte != ByteOps.FASTORE) {
                            punt = true;
                        }
                        break;
                    }
                case ByteOps.NEWARRAY_SHORT:
                    {
                        if (nextByte != ByteOps.SASTORE) {
                            punt = true;
                        }
                        break;
                    }
                case ByteOps.NEWARRAY_INT:
                    {
                        if (nextByte != ByteOps.IASTORE) {
                            punt = true;
                        }
                        break;
                    }
                case ByteOps.NEWARRAY_LONG:
                    {
                        if (nextByte != ByteOps.LASTORE) {
                            punt = true;
                        }
                        break;
                    }
                default:
                    punt = true;
                    break;
            }
            if (punt) {
                break;
            }
            lastOffset = curOffset;
            nInit++;
        }
    }
    /*
         * For singleton arrays it is still more economical to
         * generate the aput.
         */
    if (nInit < 2 || nInit != arrayLength) {
        visitor.visitNewarray(offset, 2, type, null);
        return 2;
    } else {
        visitor.visitNewarray(offset, lastOffset - offset, type, initVals);
        return lastOffset - offset;
    }
}
Also used : CstLiteralBits(com.android.dx.rop.cst.CstLiteralBits) CstInteger(com.android.dx.rop.cst.CstInteger) Constant(com.android.dx.rop.cst.Constant) CstType(com.android.dx.rop.cst.CstType) ArrayList(java.util.ArrayList)

Aggregations

CstType (com.android.dx.rop.cst.CstType)76 CstString (com.android.dx.rop.cst.CstString)29 Constant (com.android.dx.rop.cst.Constant)28 CstFieldRef (com.android.dx.rop.cst.CstFieldRef)19 CstMethodRef (com.android.dx.rop.cst.CstMethodRef)18 Type (com.android.dx.rop.type.Type)16 RegisterSpecList (com.android.dx.rop.code.RegisterSpecList)12 CstInsn (com.android.dx.dex.code.CstInsn)10 Annotations (com.android.dx.rop.annotation.Annotations)10 RegisterSpec (com.android.dx.rop.code.RegisterSpec)10 CstNat (com.android.dx.rop.cst.CstNat)10 TypeList (com.android.dx.rop.type.TypeList)9 Annotation (com.android.dx.rop.annotation.Annotation)8 ConstantPool (com.android.dx.rop.cst.ConstantPool)8 ByteArray (com.android.dx.util.ByteArray)7 IntList (com.android.dx.util.IntList)7 AttEnclosingMethod (com.android.dx.cf.attrib.AttEnclosingMethod)6 NameValuePair (com.android.dx.rop.annotation.NameValuePair)6 ThrowingCstInsn (com.android.dx.rop.code.ThrowingCstInsn)6 CstInteger (com.android.dx.rop.cst.CstInteger)6