Search in sources :

Example 1 with Label

use of org.jf.dexlib2.builder.Label in project atlas by alibaba.

the class MethodDefinition method addTries.

private void addTries(List<MethodItem> methodItems) {
    List<? extends TryBlock<? extends ExceptionHandler>> tryBlocks = methodImpl.getTryBlocks();
    if (tryBlocks.size() == 0) {
        return;
    }
    int lastInstructionAddress = instructionOffsetMap.getInstructionCodeOffset(instructions.size() - 1);
    int codeSize = lastInstructionAddress + instructions.get(instructions.size() - 1).getCodeUnits();
    for (TryBlock<? extends ExceptionHandler> tryBlock : tryBlocks) {
        int startAddress = tryBlock.getStartCodeAddress();
        int endAddress = startAddress + tryBlock.getCodeUnitCount();
        if (startAddress >= codeSize) {
            throw new RuntimeException(String.format("Try start offset %d is past the end of the code block.", startAddress));
        }
        // Note: not >=. endAddress == codeSize is valid, when the try covers the last instruction
        if (endAddress > codeSize) {
            throw new RuntimeException(String.format("Try end offset %d is past the end of the code block.", endAddress));
        }
        /**
             * The end address points to the address immediately after the end of the last
             * instruction that the try block covers. We want the .catch directive and end_try
             * label to be associated with the last covered instruction, so we need to get
             * the address for that instruction
             */
        int lastCoveredIndex = instructionOffsetMap.getInstructionIndexAtCodeOffset(endAddress - 1, false);
        int lastCoveredAddress = instructionOffsetMap.getInstructionCodeOffset(lastCoveredIndex);
        for (ExceptionHandler handler : tryBlock.getExceptionHandlers()) {
            int handlerAddress = handler.getHandlerCodeAddress();
            if (handlerAddress >= codeSize) {
                throw new ExceptionWithContext("Exception handler offset %d is past the end of the code block.", handlerAddress);
            }
            //use the address from the last covered instruction
            CatchMethodItem catchMethodItem = new CatchMethodItem(classDef.options, labelCache, lastCoveredAddress, handler.getExceptionType(), startAddress, endAddress, handlerAddress);
            methodItems.add(catchMethodItem);
        }
    }
}
Also used : ExceptionHandler(org.jf.dexlib2.iface.ExceptionHandler) ExceptionWithContext(org.jf.util.ExceptionWithContext)

Example 2 with Label

use of org.jf.dexlib2.builder.Label in project smali by JesusFreke.

the class SmalideaPackedSwitchPayload method getSwitchElements.

@Nonnull
@Override
public List<? extends SwitchElement> getSwitchElements() {
    final SmaliLiteral startKey = psiInstruction.getPackedSwitchStartKey();
    assert startKey != null;
    List<SmaliPackedSwitchElement> elements = psiInstruction.getPackedSwitchElements();
    SmaliMethod smaliMethod = psiInstruction.getParentMethod();
    SmaliInstruction packedSwitchInstruction = InstructionUtils.findFirstInstructionWithTarget(smaliMethod, Opcode.PACKED_SWITCH, psiInstruction.getOffset());
    final int baseOffset;
    if (packedSwitchInstruction == null) {
        baseOffset = 0;
    } else {
        baseOffset = packedSwitchInstruction.getOffset();
    }
    List<SwitchElement> newElements = Lists.newArrayList();
    // TODO: check for integer wraparound (how does art/dalvik handle that?)
    int initialKey = (int) startKey.getIntegralValue();
    for (int i = 0; i < elements.size(); i++) {
        final SmaliPackedSwitchElement element = elements.get(i);
        final int key = initialKey + i;
        newElements.add(new SwitchElement() {

            @Override
            public int getKey() {
                return key;
            }

            @Override
            public int getOffset() {
                SmaliLabelReference labelReference = element.getTarget();
                if (labelReference == null) {
                    return 0;
                }
                SmaliLabel label = labelReference.resolve();
                if (label == null) {
                    return 0;
                }
                return label.getOffset() - baseOffset;
            }
        });
    }
    return newElements;
}
Also used : SwitchElement(org.jf.dexlib2.iface.instruction.SwitchElement) Nonnull(javax.annotation.Nonnull)

Example 3 with Label

use of org.jf.dexlib2.builder.Label in project smali by JesusFreke.

the class SmalideaSparseSwitchPayload method getSwitchElements.

@Nonnull
@Override
public List<? extends SwitchElement> getSwitchElements() {
    List<SmaliSparseSwitchElement> elements = psiInstruction.getSparseSwitchElements();
    SmaliMethod smaliMethod = psiInstruction.getParentMethod();
    SmaliInstruction sparseSwitchInstruction = InstructionUtils.findFirstInstructionWithTarget(smaliMethod, Opcode.SPARSE_SWITCH, psiInstruction.getOffset());
    final int baseOffset;
    if (sparseSwitchInstruction == null) {
        baseOffset = 0;
    } else {
        baseOffset = sparseSwitchInstruction.getOffset();
    }
    return Lists.transform(elements, new Function<SmaliSparseSwitchElement, SwitchElement>() {

        @Override
        public SwitchElement apply(final SmaliSparseSwitchElement element) {
            return new SwitchElement() {

                @Override
                public int getKey() {
                    return (int) element.getKey().getIntegralValue();
                }

                @Override
                public int getOffset() {
                    SmaliLabelReference labelReference = element.getTarget();
                    if (labelReference == null) {
                        return 0;
                    }
                    SmaliLabel label = labelReference.resolve();
                    if (label == null) {
                        return 0;
                    }
                    return label.getOffset() - baseOffset;
                }
            };
        }
    });
}
Also used : SwitchElement(org.jf.dexlib2.iface.instruction.SwitchElement) Nonnull(javax.annotation.Nonnull)

Example 4 with Label

use of org.jf.dexlib2.builder.Label in project smali by JesusFreke.

the class FixGotoTest method testFixGotoToGoto16.

@Test
public void testFixGotoToGoto16() {
    MethodImplementationBuilder builder = new MethodImplementationBuilder(1);
    Label gotoTarget = builder.getLabel("gotoTarget");
    builder.addInstruction(new BuilderInstruction10t(Opcode.GOTO, gotoTarget));
    for (int i = 0; i < 500; i++) {
        builder.addInstruction(new BuilderInstruction10x(Opcode.NOP));
    }
    builder.addLabel("gotoTarget");
    builder.addInstruction(new BuilderInstruction10x(Opcode.RETURN_VOID));
    MethodImplementation impl = builder.getMethodImplementation();
    List<? extends Instruction> instructions = Lists.newArrayList(impl.getInstructions());
    Assert.assertEquals(502, instructions.size());
    Assert.assertEquals(Opcode.GOTO_16, instructions.get(0).getOpcode());
    Assert.assertEquals(502, ((OffsetInstruction) instructions.get(0)).getCodeOffset());
}
Also used : MethodImplementation(org.jf.dexlib2.iface.MethodImplementation) BuilderInstruction10x(org.jf.dexlib2.builder.instruction.BuilderInstruction10x) BuilderInstruction10t(org.jf.dexlib2.builder.instruction.BuilderInstruction10t) Test(org.junit.Test)

Example 5 with Label

use of org.jf.dexlib2.builder.Label in project smali by JesusFreke.

the class FixGotoTest method testFixGoto16ToGoto32.

@Test
public void testFixGoto16ToGoto32() {
    MethodImplementationBuilder builder = new MethodImplementationBuilder(1);
    Label gotoTarget = builder.getLabel("gotoTarget");
    builder.addInstruction(new BuilderInstruction20t(Opcode.GOTO_16, gotoTarget));
    for (int i = 0; i < 70000; i++) {
        builder.addInstruction(new BuilderInstruction10x(Opcode.NOP));
    }
    builder.addLabel("gotoTarget");
    builder.addInstruction(new BuilderInstruction10x(Opcode.RETURN_VOID));
    MethodImplementation impl = builder.getMethodImplementation();
    List<? extends Instruction> instructions = Lists.newArrayList(impl.getInstructions());
    Assert.assertEquals(70002, instructions.size());
    Assert.assertEquals(Opcode.GOTO_32, instructions.get(0).getOpcode());
    Assert.assertEquals(70003, ((OffsetInstruction) instructions.get(0)).getCodeOffset());
}
Also used : MethodImplementation(org.jf.dexlib2.iface.MethodImplementation) BuilderInstruction10x(org.jf.dexlib2.builder.instruction.BuilderInstruction10x) BuilderInstruction20t(org.jf.dexlib2.builder.instruction.BuilderInstruction20t) Test(org.junit.Test)

Aggregations

Test (org.junit.Test)8 BuilderInstruction10x (org.jf.dexlib2.builder.instruction.BuilderInstruction10x)6 MethodImplementation (org.jf.dexlib2.iface.MethodImplementation)6 Label (org.jf.dexlib2.builder.Label)4 BuilderInstruction10t (org.jf.dexlib2.builder.instruction.BuilderInstruction10t)4 Instruction (org.jf.dexlib2.iface.instruction.Instruction)4 Nonnull (javax.annotation.Nonnull)3 BuilderInstruction (org.jf.dexlib2.builder.BuilderInstruction)3 SwitchElement (org.jf.dexlib2.iface.instruction.SwitchElement)3 IdentityStmt (soot.jimple.IdentityStmt)3 MonitorStmt (soot.jimple.MonitorStmt)3 NopStmt (soot.jimple.NopStmt)3 Stmt (soot.jimple.Stmt)3 HashMap (java.util.HashMap)2 LinkedHashMap (java.util.LinkedHashMap)2 BuilderOffsetInstruction (org.jf.dexlib2.builder.BuilderOffsetInstruction)2 BuilderInstruction20t (org.jf.dexlib2.builder.instruction.BuilderInstruction20t)2 ExceptionHandler (org.jf.dexlib2.iface.ExceptionHandler)2 OffsetInstruction (org.jf.dexlib2.iface.instruction.OffsetInstruction)2 Instruction31t (org.jf.dexlib2.iface.instruction.formats.Instruction31t)2