Search in sources :

Example 1 with CstNat

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

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

the class MemberListParser method parse.

/**
     * Does the actual parsing.
     */
private void parse() {
    int attributeContext = getAttributeContext();
    int count = getCount();
    // Skip the count.
    int at = offset + 2;
    ByteArray bytes = cf.getBytes();
    ConstantPool pool = cf.getConstantPool();
    if (observer != null) {
        observer.parsed(bytes, offset, 2, humanName() + "s_count: " + Hex.u2(count));
    }
    for (int i = 0; i < count; i++) {
        try {
            int accessFlags = bytes.getUnsignedShort(at);
            int nameIdx = bytes.getUnsignedShort(at + 2);
            int descIdx = bytes.getUnsignedShort(at + 4);
            CstString name = (CstString) pool.get(nameIdx);
            CstString desc = (CstString) pool.get(descIdx);
            if (observer != null) {
                observer.startParsingMember(bytes, at, name.getString(), desc.getString());
                observer.parsed(bytes, at, 0, "\n" + humanName() + "s[" + i + "]:\n");
                observer.changeIndent(1);
                observer.parsed(bytes, at, 2, "access_flags: " + humanAccessFlags(accessFlags));
                observer.parsed(bytes, at + 2, 2, "name: " + name.toHuman());
                observer.parsed(bytes, at + 4, 2, "descriptor: " + desc.toHuman());
            }
            at += 6;
            AttributeListParser parser = new AttributeListParser(cf, attributeContext, at, attributeFactory);
            parser.setObserver(observer);
            at = parser.getEndOffset();
            StdAttributeList attributes = parser.getList();
            attributes.setImmutable();
            CstNat nat = new CstNat(name, desc);
            Member member = set(i, accessFlags, nat, attributes);
            if (observer != null) {
                observer.changeIndent(-1);
                observer.parsed(bytes, at, 0, "end " + humanName() + "s[" + i + "]\n");
                observer.endParsingMember(bytes, at, name.getString(), desc.getString(), member);
            }
        } catch (ParseException ex) {
            ex.addContext("...while parsing " + humanName() + "s[" + i + "]");
            throw ex;
        } catch (RuntimeException ex) {
            ParseException pe = new ParseException(ex);
            pe.addContext("...while parsing " + humanName() + "s[" + i + "]");
            throw pe;
        }
    }
    endOffset = at;
}
Also used : StdAttributeList(com.android.dx.cf.iface.StdAttributeList) CstNat(com.android.dx.rop.cst.CstNat) ConstantPool(com.android.dx.rop.cst.ConstantPool) CstString(com.android.dx.rop.cst.CstString) ByteArray(com.android.dx.util.ByteArray) ParseException(com.android.dx.cf.iface.ParseException) Member(com.android.dx.cf.iface.Member)

Example 3 with CstNat

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

the class AnnotationParser method parseValue.

/**
     * Parses an annotation value.
     *
     * @return {@code non-null;} the parsed value
     */
private Constant parseValue() throws IOException {
    int tag = input.readUnsignedByte();
    if (observer != null) {
        CstString humanTag = new CstString(Character.toString((char) tag));
        parsed(1, "tag: " + humanTag.toQuoted());
    }
    switch(tag) {
        case 'B':
            {
                CstInteger value = (CstInteger) parseConstant();
                return CstByte.make(value.getValue());
            }
        case 'C':
            {
                CstInteger value = (CstInteger) parseConstant();
                int intValue = value.getValue();
                return CstChar.make(value.getValue());
            }
        case 'D':
            {
                CstDouble value = (CstDouble) parseConstant();
                return value;
            }
        case 'F':
            {
                CstFloat value = (CstFloat) parseConstant();
                return value;
            }
        case 'I':
            {
                CstInteger value = (CstInteger) parseConstant();
                return value;
            }
        case 'J':
            {
                CstLong value = (CstLong) parseConstant();
                return value;
            }
        case 'S':
            {
                CstInteger value = (CstInteger) parseConstant();
                return CstShort.make(value.getValue());
            }
        case 'Z':
            {
                CstInteger value = (CstInteger) parseConstant();
                return CstBoolean.make(value.getValue());
            }
        case 'c':
            {
                int classInfoIndex = input.readUnsignedShort();
                CstString value = (CstString) pool.get(classInfoIndex);
                Type type = Type.internReturnType(value.getString());
                if (observer != null) {
                    parsed(2, "class_info: " + type.toHuman());
                }
                return new CstType(type);
            }
        case 's':
            {
                return parseConstant();
            }
        case 'e':
            {
                requireLength(4);
                int typeNameIndex = input.readUnsignedShort();
                int constNameIndex = input.readUnsignedShort();
                CstString typeName = (CstString) pool.get(typeNameIndex);
                CstString constName = (CstString) pool.get(constNameIndex);
                if (observer != null) {
                    parsed(2, "type_name: " + typeName.toHuman());
                    parsed(2, "const_name: " + constName.toHuman());
                }
                return new CstEnumRef(new CstNat(constName, typeName));
            }
        case '@':
            {
                Annotation annotation = parseAnnotation(AnnotationVisibility.EMBEDDED);
                return new CstAnnotation(annotation);
            }
        case '[':
            {
                requireLength(2);
                int numValues = input.readUnsignedShort();
                CstArray.List list = new CstArray.List(numValues);
                if (observer != null) {
                    parsed(2, "num_values: " + numValues);
                    changeIndent(1);
                }
                for (int i = 0; i < numValues; i++) {
                    if (observer != null) {
                        changeIndent(-1);
                        parsed(0, "element_value[" + i + "]:");
                        changeIndent(1);
                    }
                    list.set(i, parseValue());
                }
                if (observer != null) {
                    changeIndent(-1);
                }
                list.setImmutable();
                return new CstArray(list);
            }
        default:
            {
                throw new ParseException("unknown annotation tag: " + Hex.u1(tag));
            }
    }
}
Also used : CstFloat(com.android.dx.rop.cst.CstFloat) CstNat(com.android.dx.rop.cst.CstNat) CstArray(com.android.dx.rop.cst.CstArray) CstLong(com.android.dx.rop.cst.CstLong) CstString(com.android.dx.rop.cst.CstString) CstAnnotation(com.android.dx.rop.cst.CstAnnotation) CstDouble(com.android.dx.rop.cst.CstDouble) CstEnumRef(com.android.dx.rop.cst.CstEnumRef) Annotation(com.android.dx.rop.annotation.Annotation) CstAnnotation(com.android.dx.rop.cst.CstAnnotation) Type(com.android.dx.rop.type.Type) CstType(com.android.dx.rop.cst.CstType) CstInteger(com.android.dx.rop.cst.CstInteger) CstType(com.android.dx.rop.cst.CstType) AnnotationsList(com.android.dx.rop.annotation.AnnotationsList) ParseException(com.android.dx.cf.iface.ParseException)

Example 4 with CstNat

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

the class EscapeAnalysis method insertExceptionThrow.

/**
     * Replaces instructions that trigger an ArrayIndexOutofBounds exception
     * with an actual throw of the exception.
     *
     * @param insn {@code non-null;} instruction causing the exception
     * @param index {@code non-null;} index value that is out of bounds
     * @param deletedInsns {@code non-null;} set of instructions marked for
     * deletion
     */
private void insertExceptionThrow(SsaInsn insn, RegisterSpec index, HashSet<SsaInsn> deletedInsns) {
    // Create a new ArrayIndexOutOfBoundsException
    CstType exception = new CstType(Exceptions.TYPE_ArrayIndexOutOfBoundsException);
    insertThrowingInsnBefore(insn, RegisterSpecList.EMPTY, null, RegOps.NEW_INSTANCE, exception);
    // Add a successor block with a move result pseudo for the exception
    SsaBasicBlock currBlock = insn.getBlock();
    SsaBasicBlock newBlock = currBlock.insertNewSuccessor(currBlock.getPrimarySuccessor());
    SsaInsn newInsn = newBlock.getInsns().get(0);
    RegisterSpec newReg = RegisterSpec.make(ssaMeth.makeNewSsaReg(), exception);
    insertPlainInsnBefore(newInsn, RegisterSpecList.EMPTY, newReg, RegOps.MOVE_RESULT_PSEUDO, null);
    // Add another successor block to initialize the exception
    SsaBasicBlock newBlock2 = newBlock.insertNewSuccessor(newBlock.getPrimarySuccessor());
    SsaInsn newInsn2 = newBlock2.getInsns().get(0);
    CstNat newNat = new CstNat(new CstString("<init>"), new CstString("(I)V"));
    CstMethodRef newRef = new CstMethodRef(exception, newNat);
    insertThrowingInsnBefore(newInsn2, RegisterSpecList.make(newReg, index), null, RegOps.INVOKE_DIRECT, newRef);
    deletedInsns.add(newInsn2);
    // Add another successor block to throw the new exception
    SsaBasicBlock newBlock3 = newBlock2.insertNewSuccessor(newBlock2.getPrimarySuccessor());
    SsaInsn newInsn3 = newBlock3.getInsns().get(0);
    insertThrowingInsnBefore(newInsn3, RegisterSpecList.make(newReg), null, RegOps.THROW, null);
    newBlock3.replaceSuccessor(newBlock3.getPrimarySuccessorIndex(), ssaMeth.getExitBlock().getIndex());
    deletedInsns.add(newInsn3);
}
Also used : CstNat(com.android.dx.rop.cst.CstNat) CstType(com.android.dx.rop.cst.CstType) CstString(com.android.dx.rop.cst.CstString) CstMethodRef(com.android.dx.rop.cst.CstMethodRef) RegisterSpec(com.android.dx.rop.code.RegisterSpec)

Example 5 with CstNat

use of com.android.dx.rop.cst.CstNat in project J2ME-Loader by nikita36078.

the class Main method dumpMethod.

/**
 * Dumps any method with the given name in the given file.
 *
 * @param dex {@code non-null;} the dex file
 * @param fqName {@code non-null;} the fully-qualified name of the
 * method(s)
 * @param out {@code non-null;} where to dump to
 */
private void dumpMethod(DexFile dex, String fqName, OutputStreamWriter out) {
    boolean wildcard = fqName.endsWith("*");
    int lastDot = fqName.lastIndexOf('.');
    if ((lastDot <= 0) || (lastDot == (fqName.length() - 1))) {
        context.err.println("bogus fully-qualified method name: " + fqName);
        return;
    }
    String className = fqName.substring(0, lastDot).replace('.', '/');
    String methodName = fqName.substring(lastDot + 1);
    ClassDefItem clazz = dex.getClassOrNull(className);
    if (clazz == null) {
        context.err.println("no such class: " + className);
        return;
    }
    if (wildcard) {
        methodName = methodName.substring(0, methodName.length() - 1);
    }
    ArrayList<EncodedMethod> allMeths = clazz.getMethods();
    TreeMap<CstNat, EncodedMethod> meths = new TreeMap<CstNat, EncodedMethod>();
    /*
         * Figure out which methods to include in the output, and get them
         * all sorted, so that the printout code is robust with respect to
         * changes in the underlying order.
         */
    for (EncodedMethod meth : allMeths) {
        String methName = meth.getName().getString();
        if ((wildcard && methName.startsWith(methodName)) || (!wildcard && methName.equals(methodName))) {
            meths.put(meth.getRef().getNat(), meth);
        }
    }
    if (meths.size() == 0) {
        context.err.println("no such method: " + fqName);
        return;
    }
    PrintWriter pw = new PrintWriter(out);
    for (EncodedMethod meth : meths.values()) {
        // TODO: Better stuff goes here, perhaps.
        meth.debugPrint(pw, args.verboseDump);
        /*
             * The (default) source file is an attribute of the class, but
             * it's useful to see it in method dumps.
             */
        CstString sourceFile = clazz.getSourceFile();
        if (sourceFile != null) {
            pw.println("  source file: " + sourceFile.toQuoted());
        }
        Annotations methodAnnotations = clazz.getMethodAnnotations(meth.getRef());
        AnnotationsList parameterAnnotations = clazz.getParameterAnnotations(meth.getRef());
        if (methodAnnotations != null) {
            pw.println("  method annotations:");
            for (Annotation a : methodAnnotations.getAnnotations()) {
                pw.println("    " + a);
            }
        }
        if (parameterAnnotations != null) {
            pw.println("  parameter annotations:");
            int sz = parameterAnnotations.size();
            for (int i = 0; i < sz; i++) {
                pw.println("    parameter " + i);
                Annotations annotations = parameterAnnotations.get(i);
                for (Annotation a : annotations.getAnnotations()) {
                    pw.println("      " + a);
                }
            }
        }
    }
    pw.flush();
}
Also used : CstNat(com.android.dx.rop.cst.CstNat) CstString(com.android.dx.rop.cst.CstString) AnnotationsList(com.android.dx.rop.annotation.AnnotationsList) CstString(com.android.dx.rop.cst.CstString) TreeMap(java.util.TreeMap) Annotation(com.android.dx.rop.annotation.Annotation) Annotations(com.android.dx.rop.annotation.Annotations) ClassDefItem(com.android.dx.dex.file.ClassDefItem) EncodedMethod(com.android.dx.dex.file.EncodedMethod) PrintWriter(java.io.PrintWriter)

Aggregations

CstNat (com.android.dx.rop.cst.CstNat)16 CstString (com.android.dx.rop.cst.CstString)10 CstType (com.android.dx.rop.cst.CstType)10 ParseException (com.android.dx.cf.iface.ParseException)6 CstMethodRef (com.android.dx.rop.cst.CstMethodRef)6 AttEnclosingMethod (com.android.dx.cf.attrib.AttEnclosingMethod)4 Annotation (com.android.dx.rop.annotation.Annotation)4 AnnotationsList (com.android.dx.rop.annotation.AnnotationsList)4 ConstantPool (com.android.dx.rop.cst.ConstantPool)4 ByteArray (com.android.dx.util.ByteArray)4 Attribute (com.android.dx.cf.iface.Attribute)2 Member (com.android.dx.cf.iface.Member)2 StdAttributeList (com.android.dx.cf.iface.StdAttributeList)2 ClassDefItem (com.android.dx.dex.file.ClassDefItem)2 EncodedMethod (com.android.dx.dex.file.EncodedMethod)2 Annotations (com.android.dx.rop.annotation.Annotations)2 RegisterSpec (com.android.dx.rop.code.RegisterSpec)2 Constant (com.android.dx.rop.cst.Constant)2 CstAnnotation (com.android.dx.rop.cst.CstAnnotation)2 CstArray (com.android.dx.rop.cst.CstArray)2