diff options
Diffstat (limited to 'src/proguard/classfile/editor/CodeAttributeEditor.java')
-rw-r--r-- | src/proguard/classfile/editor/CodeAttributeEditor.java | 142 |
1 files changed, 105 insertions, 37 deletions
diff --git a/src/proguard/classfile/editor/CodeAttributeEditor.java b/src/proguard/classfile/editor/CodeAttributeEditor.java index 337e0d4..41b7471 100644 --- a/src/proguard/classfile/editor/CodeAttributeEditor.java +++ b/src/proguard/classfile/editor/CodeAttributeEditor.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2013 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -22,6 +22,10 @@ package proguard.classfile.editor; import proguard.classfile.*; import proguard.classfile.attribute.*; +import proguard.classfile.attribute.annotation.*; +import proguard.classfile.attribute.annotation.target.*; +import proguard.classfile.attribute.annotation.target.visitor.*; +import proguard.classfile.attribute.annotation.visitor.TypeAnnotationVisitor; import proguard.classfile.attribute.preverification.*; import proguard.classfile.attribute.preverification.visitor.*; import proguard.classfile.attribute.visitor.*; @@ -47,7 +51,10 @@ implements AttributeVisitor, VerificationTypeVisitor, LineNumberInfoVisitor, LocalVariableInfoVisitor, - LocalVariableTypeInfoVisitor + LocalVariableTypeInfoVisitor, + TypeAnnotationVisitor, + TargetInfoVisitor, + LocalVariableTargetElementVisitor { //* private static final boolean DEBUG = false; @@ -179,7 +186,6 @@ implements AttributeVisitor, modified = true; simple = false; - } @@ -206,7 +212,6 @@ implements AttributeVisitor, modified = true; simple = false; - } @@ -512,6 +517,12 @@ implements AttributeVisitor, } + public void visitAnyTypeAnnotationsAttribute(Clazz clazz, TypeAnnotationsAttribute typeAnnotationsAttribute) + { + typeAnnotationsAttribute.typeAnnotationsAccept(clazz, this); + } + + /** * Checks if it is possible to modifies the given code without having to * update any offsets. @@ -840,9 +851,9 @@ implements AttributeVisitor, public void visitBranchInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, BranchInstruction branchInstruction) { - // Adjust the branch offset. - branchInstruction.branchOffset = newBranchOffset(offset, - branchInstruction.branchOffset); + // Update the branch offset, relative to the precise new offset. + branchInstruction.branchOffset = + newBranchOffset(offset, branchInstruction.branchOffset, newOffset); // Write out the instruction. instructionWriter.visitBranchInstruction(clazz, @@ -857,13 +868,14 @@ implements AttributeVisitor, public void visitTableSwitchInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, TableSwitchInstruction tableSwitchInstruction) { - // Adjust the default jump offset. - tableSwitchInstruction.defaultOffset = newBranchOffset(offset, - tableSwitchInstruction.defaultOffset); + // Update the default jump offset, relative to the precise new offset. + tableSwitchInstruction.defaultOffset = + newBranchOffset(offset, tableSwitchInstruction.defaultOffset, newOffset); - // Adjust the jump offsets. + // Update the jump offsets, relative to the precise new offset. newJumpOffsets(offset, - tableSwitchInstruction.jumpOffsets); + tableSwitchInstruction.jumpOffsets, + newOffset); // Write out the instruction. instructionWriter.visitTableSwitchInstruction(clazz, @@ -878,13 +890,14 @@ implements AttributeVisitor, public void visitLookUpSwitchInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, LookUpSwitchInstruction lookUpSwitchInstruction) { - // Adjust the default jump offset. - lookUpSwitchInstruction.defaultOffset = newBranchOffset(offset, - lookUpSwitchInstruction.defaultOffset); + // Update the default jump offset, relative to the precise new offset. + lookUpSwitchInstruction.defaultOffset = + newBranchOffset(offset, lookUpSwitchInstruction.defaultOffset, newOffset); - // Adjust the jump offsets. + // Update the jump offsets, relative to the precise new offset. newJumpOffsets(offset, - lookUpSwitchInstruction.jumpOffsets); + lookUpSwitchInstruction.jumpOffsets, + newOffset); // Write out the instruction. instructionWriter.visitLookUpSwitchInstruction(clazz, @@ -901,8 +914,8 @@ implements AttributeVisitor, public void visitExceptionInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, ExceptionInfo exceptionInfo) { - // Update the code offsets. Note that the instruction offset map also has - // an entry for the first offset after the code, for u2endPC. + // Update the code offsets. Note that the instruction offset map also + // has an entry for the first offset after the code, for u2endPC. exceptionInfo.u2startPC = newInstructionOffset(exceptionInfo.u2startPC); exceptionInfo.u2endPC = newInstructionOffset(exceptionInfo.u2endPC); exceptionInfo.u2handlerPC = newInstructionOffset(exceptionInfo.u2handlerPC); @@ -988,12 +1001,9 @@ implements AttributeVisitor, public void visitLocalVariableInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableInfo localVariableInfo) { // Update the code offset and length. - int newStartPC = newInstructionOffset(localVariableInfo.u2startPC); - int newEndPC = newInstructionOffset(localVariableInfo.u2startPC + - localVariableInfo.u2length); - - localVariableInfo.u2length = newEndPC - newStartPC; - localVariableInfo.u2startPC = newStartPC; + // Be careful to update the length first. + localVariableInfo.u2length = newBranchOffset(localVariableInfo.u2startPC, localVariableInfo.u2length); + localVariableInfo.u2startPC = newInstructionOffset(localVariableInfo.u2startPC); } @@ -1002,41 +1012,99 @@ implements AttributeVisitor, public void visitLocalVariableTypeInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTypeInfo localVariableTypeInfo) { // Update the code offset and length. - int newStartPC = newInstructionOffset(localVariableTypeInfo.u2startPC); - int newEndPC = newInstructionOffset(localVariableTypeInfo.u2startPC + - localVariableTypeInfo.u2length); + // Be careful to update the length first. + localVariableTypeInfo.u2length = newBranchOffset(localVariableTypeInfo.u2startPC, localVariableTypeInfo.u2length); + localVariableTypeInfo.u2startPC = newInstructionOffset(localVariableTypeInfo.u2startPC); + } + + + // Implementations for TypeAnnotationVisitor. + + public void visitTypeAnnotation(Clazz clazz, TypeAnnotation typeAnnotation) + { + // Update all local variable targets. + typeAnnotation.targetInfoAccept(clazz, this); + } + + + // Implementations for TargetInfoVisitor. + + public void visitAnyTargetInfo(Clazz clazz, TypeAnnotation typeAnnotation, TargetInfo targetInfo) {} + - localVariableTypeInfo.u2length = newEndPC - newStartPC; - localVariableTypeInfo.u2startPC = newStartPC; + public void visitLocalVariableTargetInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, TypeAnnotation typeAnnotation, LocalVariableTargetInfo localVariableTargetInfo) + { + // Update the offsets of the variables. + localVariableTargetInfo.targetElementsAccept(clazz, method, codeAttribute, typeAnnotation, this); + } + + + public void visitOffsetTargetInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, TypeAnnotation typeAnnotation, OffsetTargetInfo offsetTargetInfo) + { + // Update the offset. + offsetTargetInfo.u2offset = newInstructionOffset(offsetTargetInfo.u2offset); + } + + + // Implementations for LocalVariableTargetElementVisitor. + + public void visitLocalVariableTargetElement(Clazz clazz, Method method, CodeAttribute codeAttribute, TypeAnnotation typeAnnotation, LocalVariableTargetInfo localVariableTargetInfo, LocalVariableTargetElement localVariableTargetElement) + { + // Update the variable start offset and length. + // Be careful to update the length first. + localVariableTargetElement.u2length = newBranchOffset(localVariableTargetElement.u2startPC, localVariableTargetElement.u2length); + localVariableTargetElement.u2startPC = newInstructionOffset(localVariableTargetElement.u2startPC); } // Small utility methods. /** - * Adjusts the given jump offsets for the instruction at the given offset. + * Updates the given jump offsets for the instruction at the given offset, + * relative to the given new offset. */ - private void newJumpOffsets(int oldInstructionOffset, int[] oldJumpOffsets) + private void newJumpOffsets(int oldInstructionOffset, + int[] oldJumpOffsets, + int newInstructionOffset) { for (int index = 0; index < oldJumpOffsets.length; index++) { - oldJumpOffsets[index] = newBranchOffset(oldInstructionOffset, oldJumpOffsets[index]); + oldJumpOffsets[index] = newBranchOffset(oldInstructionOffset, + oldJumpOffsets[index], + newInstructionOffset); } } /** * Computes the new branch offset for the instruction at the given offset - * with the given branch offset. + * with the given branch offset, relative to the new instruction (block) + * offset. + */ + private int newBranchOffset(int oldInstructionOffset, + int oldBranchOffset) + { + return newInstructionOffset(oldInstructionOffset + oldBranchOffset) - + newInstructionOffset(oldInstructionOffset); + } + + + /** + * Computes the new branch offset for the instruction at the given offset + * with the given branch offset, relative to the given new offset. */ - private int newBranchOffset(int oldInstructionOffset, int oldBranchOffset) + private int newBranchOffset(int oldInstructionOffset, + int oldBranchOffset, + int newInstructionOffset) { - return newInstructionOffset(oldInstructionOffset + oldBranchOffset) - newOffset; + return newInstructionOffset(oldInstructionOffset + oldBranchOffset) - + newInstructionOffset; } /** - * Computes the new instruction offset for the instruction at the given offset. + * Computes the new instruction offset for the instruction at the given + * offset. */ private int newInstructionOffset(int oldInstructionOffset) { |