Search in sources :

Example 46 with CstType

use of com.android.dx.rop.cst.CstType in project RocooFix by dodola.

the class ClassReferenceListBuilder method addClassWithHierachy.

private void addClassWithHierachy(String classBinaryName) {
    if (classNames.contains(classBinaryName) || !refcname.equals(classBinaryName + CLASS_EXTENSION)) {
        return;
    }
    try {
        DirectClassFile classFile = path.getClass(currentName);
        classNames.add(currentName);
        File entryFile = new File(patchDir + "/" + currentName);
        entryFile.getParentFile().mkdirs();
        if (!entryFile.exists()) {
            entryFile.createNewFile();
            //                Iterable<ClassPathElement> elements = path.getElements();
            //                for (ClassPathElement element : elements) {
            //                    InputStream in = element.open(currentName);
            byte[] bytes = NuwaProcessor.referHackWhenInit(classFile.getBytes().makeDataInputStream());
            //                    System.out.println(classFile.getFilePath() + ",size:" + bytes.length);
            FileUtils.writeByteArrayToFile(entryFile, bytes);
        //                }
        }
        //            NuwaProcessor.referHackWhenInit();
        CstType superClass = classFile.getSuperclass();
        if (superClass != null) {
            addClassWithHierachy(superClass.getClassType().getClassName());
        }
        TypeList interfaceList = classFile.getInterfaces();
        int interfaceNumber = interfaceList.size();
        for (int i = 0; i < interfaceNumber; i++) {
            addClassWithHierachy(interfaceList.getType(i).getClassName());
        }
    } catch (FileNotFoundException e) {
    } catch (IOException e) {
        e.printStackTrace();
    }
}
Also used : DirectClassFile(com.android.dx.cf.direct.DirectClassFile) CstType(com.android.dx.rop.cst.CstType) FileNotFoundException(java.io.FileNotFoundException) IOException(java.io.IOException) JarFile(java.util.jar.JarFile) File(java.io.File) DirectClassFile(com.android.dx.cf.direct.DirectClassFile) StdTypeList(com.android.dx.rop.type.StdTypeList) TypeList(com.android.dx.rop.type.TypeList)

Example 47 with CstType

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

the class ClassReferenceListBuilder method addClassWithHierarchy.

private void addClassWithHierarchy(String classBinaryName) {
    if (classNames.contains(classBinaryName)) {
        return;
    }
    try {
        DirectClassFile classFile = path.getClass(classBinaryName + CLASS_EXTENSION);
        if (CLASS_TO_CHECK != null && classBinaryName.contains(CLASS_TO_CHECK)) {
            found();
        }
        classNames.add(classBinaryName);
        CstType superClass = classFile.getSuperclass();
        if (superClass != null) {
            addClassWithHierarchy(superClass.getClassType().getClassName());
        }
        TypeList interfaceList = classFile.getInterfaces();
        int interfaceNumber = interfaceList.size();
        for (int i = 0; i < interfaceNumber; i++) {
            addClassWithHierarchy(interfaceList.getType(i).getClassName());
        }
    } catch (FileNotFoundException e) {
    // Ignore: The referenced type is not in the path it must be part of the libraries.
    }
}
Also used : DirectClassFile(com.android.dx.cf.direct.DirectClassFile) CstType(com.android.dx.rop.cst.CstType) FileNotFoundException(java.io.FileNotFoundException) StdTypeList(com.android.dx.rop.type.StdTypeList) TypeList(com.android.dx.rop.type.TypeList)

Example 48 with CstType

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

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

the class StdAttributeFactory method innerClasses.

/**
     * Parses an {@code InnerClasses} attribute.
     */
private Attribute innerClasses(DirectClassFile cf, int offset, int length, ParseObserver observer) {
    if (length < 2) {
        return throwSeverelyTruncated();
    }
    ByteArray bytes = cf.getBytes();
    ConstantPool pool = cf.getConstantPool();
    // number_of_classes
    int count = bytes.getUnsignedShort(offset);
    if (observer != null) {
        observer.parsed(bytes, offset, 2, "number_of_classes: " + Hex.u2(count));
    }
    offset += 2;
    length -= 2;
    if (length != (count * 8)) {
        throwBadLength((count * 8) + 2);
    }
    InnerClassList list = new InnerClassList(count);
    for (int i = 0; i < count; i++) {
        int innerClassIdx = bytes.getUnsignedShort(offset);
        int outerClassIdx = bytes.getUnsignedShort(offset + 2);
        int nameIdx = bytes.getUnsignedShort(offset + 4);
        int accessFlags = bytes.getUnsignedShort(offset + 6);
        CstType innerClass = (CstType) pool.get(innerClassIdx);
        CstType outerClass = (CstType) pool.get0Ok(outerClassIdx);
        CstString name = (CstString) pool.get0Ok(nameIdx);
        list.set(i, innerClass, outerClass, name, accessFlags);
        if (observer != null) {
            observer.parsed(bytes, offset, 2, "inner_class: " + DirectClassFile.stringOrNone(innerClass));
            observer.parsed(bytes, offset + 2, 2, "  outer_class: " + DirectClassFile.stringOrNone(outerClass));
            observer.parsed(bytes, offset + 4, 2, "  name: " + DirectClassFile.stringOrNone(name));
            observer.parsed(bytes, offset + 6, 2, "  access_flags: " + AccessFlags.innerClassString(accessFlags));
        }
        offset += 8;
    }
    list.setImmutable();
    return new AttInnerClasses(list);
}
Also used : ConstantPool(com.android.dx.rop.cst.ConstantPool) CstType(com.android.dx.rop.cst.CstType) CstString(com.android.dx.rop.cst.CstString) ByteArray(com.android.dx.util.ByteArray) InnerClassList(com.android.dx.cf.attrib.InnerClassList) AttInnerClasses(com.android.dx.cf.attrib.AttInnerClasses)

Example 50 with CstType

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

the class Ropper method processBlock.

/**
     * Processes the given block.
     *
     * @param block {@code non-null;} block to process
     * @param frame {@code non-null;} start frame for the block
     * @param workSet {@code non-null;} bits representing work to do,
     * which this method may add to
     */
private void processBlock(ByteBlock block, Frame frame, int[] workSet) {
    // Prepare the list of caught exceptions for this block.
    ByteCatchList catches = block.getCatches();
    machine.startBlock(catches.toRopCatchList());
    /*
         * Using a copy of the given frame, simulate each instruction,
         * calling into machine for each.
         */
    frame = frame.copy();
    sim.simulate(block, frame);
    frame.setImmutable();
    int extraBlockCount = machine.getExtraBlockCount();
    ArrayList<Insn> insns = machine.getInsns();
    int insnSz = insns.size();
    /*
         * Merge the frame into each possible non-exceptional
         * successor.
         */
    int catchSz = catches.size();
    IntList successors = block.getSuccessors();
    int startSuccessorIndex;
    Subroutine calledSubroutine = null;
    if (machine.hasJsr()) {
        /*
             * If this frame ends in a JSR, only merge our frame with
             * the subroutine start, not the subroutine's return target.
             */
        startSuccessorIndex = 1;
        int subroutineLabel = successors.get(1);
        if (subroutines[subroutineLabel] == null) {
            subroutines[subroutineLabel] = new Subroutine(subroutineLabel);
        }
        subroutines[subroutineLabel].addCallerBlock(block.getLabel());
        calledSubroutine = subroutines[subroutineLabel];
    } else if (machine.hasRet()) {
        /*
             * This block ends in a ret, which means it's the final block
             * in some subroutine. Ultimately, this block will be copied
             * and inlined for each call and then disposed of.
             */
        ReturnAddress ra = machine.getReturnAddress();
        int subroutineLabel = ra.getSubroutineAddress();
        if (subroutines[subroutineLabel] == null) {
            subroutines[subroutineLabel] = new Subroutine(subroutineLabel, block.getLabel());
        } else {
            subroutines[subroutineLabel].addRetBlock(block.getLabel());
        }
        successors = subroutines[subroutineLabel].getSuccessors();
        subroutines[subroutineLabel].mergeToSuccessors(frame, workSet);
        // Skip processing below since we just did it.
        startSuccessorIndex = successors.size();
    } else if (machine.wereCatchesUsed()) {
        /*
             * If there are catches, then the first successors
             * (which will either be all of them or all but the last one)
             * are catch targets.
             */
        startSuccessorIndex = catchSz;
    } else {
        startSuccessorIndex = 0;
    }
    int succSz = successors.size();
    for (int i = startSuccessorIndex; i < succSz; i++) {
        int succ = successors.get(i);
        try {
            mergeAndWorkAsNecessary(succ, block.getLabel(), calledSubroutine, frame, workSet);
        } catch (SimException ex) {
            ex.addContext("...while merging to block " + Hex.u2(succ));
            throw ex;
        }
    }
    if ((succSz == 0) && machine.returns()) {
        /*
             * The block originally contained a return, but it has
             * been made to instead end with a goto, and we need to
             * tell it at this point that its sole successor is the
             * return block. This has to happen after the merge loop
             * above, since, at this point, the return block doesn't
             * actually exist; it gets synthesized at the end of
             * processing the original blocks.
             */
        successors = IntList.makeImmutable(getSpecialLabel(RETURN));
        succSz = 1;
    }
    int primarySucc;
    if (succSz == 0) {
        primarySucc = -1;
    } else {
        primarySucc = machine.getPrimarySuccessorIndex();
        if (primarySucc >= 0) {
            primarySucc = successors.get(primarySucc);
        }
    }
    /*
         * This variable is true only when the method is synchronized and
         * the block being processed can possibly throw an exception.
         */
    boolean synch = isSynchronized() && machine.canThrow();
    if (synch || (catchSz != 0)) {
        /*
             * Deal with exception handlers: Merge an exception-catch
             * frame into each possible exception handler, and
             * construct a new set of successors to point at the
             * exception handler setup blocks (which get synthesized
             * at the very end of processing).
             */
        boolean catchesAny = false;
        IntList newSucc = new IntList(succSz);
        for (int i = 0; i < catchSz; i++) {
            ByteCatchList.Item one = catches.get(i);
            CstType exceptionClass = one.getExceptionClass();
            int targ = one.getHandlerPc();
            catchesAny |= (exceptionClass == CstType.OBJECT);
            Frame f = frame.makeExceptionHandlerStartFrame(exceptionClass);
            try {
                mergeAndWorkAsNecessary(targ, block.getLabel(), null, f, workSet);
            } catch (SimException ex) {
                ex.addContext("...while merging exception to block " + Hex.u2(targ));
                throw ex;
            }
            /*
                 * Set up the exception handler type.
                 */
            CatchInfo handlers = catchInfos[targ];
            if (handlers == null) {
                handlers = new CatchInfo();
                catchInfos[targ] = handlers;
            }
            ExceptionHandlerSetup handler = handlers.getSetup(exceptionClass.getClassType());
            /*
                 * The synthesized exception setup block will have the label given by handler.
                 */
            newSucc.add(handler.getLabel());
        }
        if (synch && !catchesAny) {
            /*
                 * The method is synchronized and this block doesn't
                 * already have a catch-all handler, so add one to the
                 * end, both in the successors and in the throwing
                 * instruction(s) at the end of the block (which is where
                 * the caught classes live).
                 */
            newSucc.add(getSpecialLabel(SYNCH_CATCH_1));
            synchNeedsExceptionHandler = true;
            for (int i = insnSz - extraBlockCount - 1; i < insnSz; i++) {
                Insn insn = insns.get(i);
                if (insn.canThrow()) {
                    insn = insn.withAddedCatch(Type.OBJECT);
                    insns.set(i, insn);
                }
            }
        }
        if (primarySucc >= 0) {
            newSucc.add(primarySucc);
        }
        newSucc.setImmutable();
        successors = newSucc;
    }
    // Construct the final resulting block(s), and store it (them).
    int primarySuccListIndex = successors.indexOf(primarySucc);
    /*
         * If there are any extra blocks, work backwards through the
         * list of instructions, adding single-instruction blocks, and
         * resetting the successors variables as appropriate.
         */
    for (; /*extraBlockCount*/
    extraBlockCount > 0; extraBlockCount--) {
        /*
             * Some of the blocks that the RopperMachine wants added
             * are for move-result insns, and these need goto insns as well.
             */
        Insn extraInsn = insns.get(--insnSz);
        boolean needsGoto = extraInsn.getOpcode().getBranchingness() == Rop.BRANCH_NONE;
        InsnList il = new InsnList(needsGoto ? 2 : 1);
        IntList extraBlockSuccessors = successors;
        il.set(0, extraInsn);
        if (needsGoto) {
            il.set(1, new PlainInsn(Rops.GOTO, extraInsn.getPosition(), null, RegisterSpecList.EMPTY));
            /*
                 * Obviously, this block won't be throwing an exception
                 * so it should only have one successor.
                 */
            extraBlockSuccessors = IntList.makeImmutable(primarySucc);
        }
        il.setImmutable();
        int label = getAvailableLabel();
        BasicBlock bb = new BasicBlock(label, il, extraBlockSuccessors, primarySucc);
        // All of these extra blocks will be in the same subroutine
        addBlock(bb, frame.getSubroutines());
        successors = successors.mutableCopy();
        successors.set(primarySuccListIndex, label);
        successors.setImmutable();
        primarySucc = label;
    }
    Insn lastInsn = (insnSz == 0) ? null : insns.get(insnSz - 1);
    /*
         * Add a goto to the end of the block if it doesn't already
         * end with a branch, to maintain the invariant that all
         * blocks end with a branch of some sort or other. Note that
         * it is possible for there to be blocks for which no
         * instructions were ever output (e.g., only consist of pop*
         * in the original Java bytecode).
         */
    if ((lastInsn == null) || (lastInsn.getOpcode().getBranchingness() == Rop.BRANCH_NONE)) {
        SourcePosition pos = (lastInsn == null) ? SourcePosition.NO_INFO : lastInsn.getPosition();
        insns.add(new PlainInsn(Rops.GOTO, pos, null, RegisterSpecList.EMPTY));
        insnSz++;
    }
    /*
         * Construct a block for the remaining instructions (which in
         * the usual case is all of them).
         */
    InsnList il = new InsnList(insnSz);
    for (int i = 0; i < insnSz; i++) {
        il.set(i, insns.get(i));
    }
    il.setImmutable();
    BasicBlock bb = new BasicBlock(block.getLabel(), il, successors, primarySucc);
    addOrReplaceBlock(bb, frame.getSubroutines());
}
Also used : ThrowingCstInsn(com.android.dx.rop.code.ThrowingCstInsn) ThrowingInsn(com.android.dx.rop.code.ThrowingInsn) PlainInsn(com.android.dx.rop.code.PlainInsn) Insn(com.android.dx.rop.code.Insn) PlainCstInsn(com.android.dx.rop.code.PlainCstInsn) BasicBlock(com.android.dx.rop.code.BasicBlock) InsnList(com.android.dx.rop.code.InsnList) IntList(com.android.dx.util.IntList) PlainInsn(com.android.dx.rop.code.PlainInsn) CstType(com.android.dx.rop.cst.CstType) SourcePosition(com.android.dx.rop.code.SourcePosition)

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