• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * ProGuard -- shrinking, optimization, obfuscation, and preverification
3  *             of Java bytecode.
4  *
5  * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
6  *
7  * This program is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU General Public License as published by the Free
9  * Software Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * This program is distributed in the hope that it will be useful, but WITHOUT
13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15  * more details.
16  *
17  * You should have received a copy of the GNU General Public License along
18  * with this program; if not, write to the Free Software Foundation, Inc.,
19  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20  */
21 package proguard.optimize;
22 
23 import proguard.classfile.*;
24 import proguard.classfile.attribute.*;
25 import proguard.classfile.attribute.annotation.*;
26 import proguard.classfile.attribute.preverification.*;
27 import proguard.classfile.attribute.visitor.AttributeVisitor;
28 import proguard.classfile.util.ClassUtil;
29 
30 /**
31  * This AttributeVisitor delegates its call to another AttributeVisitor, and
32  * prints out the code if the other visitor has changed it.
33  *
34  * @author Eric Lafortune
35  */
36 public class ChangedCodePrinter
37 implements   AttributeVisitor
38 {
39     private final AttributeVisitor attributeVisitor;
40 
41 
ChangedCodePrinter(AttributeVisitor attributeVisitor)42     public ChangedCodePrinter(AttributeVisitor attributeVisitor)
43     {
44         this.attributeVisitor = attributeVisitor;
45     }
46 
47 
48     // Implementations for AttributeVisitor.
49 
visitUnknownAttribute(Clazz clazz, UnknownAttribute unknownAttribute)50     public void visitUnknownAttribute(Clazz clazz, UnknownAttribute unknownAttribute)
51     {
52         attributeVisitor.visitUnknownAttribute(clazz, unknownAttribute);
53     }
54 
55 
visitBootstrapMethodsAttribute(Clazz clazz, BootstrapMethodsAttribute bootstrapMethodsAttribute)56     public void visitBootstrapMethodsAttribute(Clazz clazz, BootstrapMethodsAttribute bootstrapMethodsAttribute)
57     {
58         attributeVisitor.visitBootstrapMethodsAttribute(clazz, bootstrapMethodsAttribute);
59     }
60 
61 
visitSourceFileAttribute(Clazz clazz, SourceFileAttribute sourceFileAttribute)62     public void visitSourceFileAttribute(Clazz clazz, SourceFileAttribute sourceFileAttribute)
63     {
64         attributeVisitor.visitSourceFileAttribute(clazz, sourceFileAttribute);
65     }
66 
67 
visitSourceDirAttribute(Clazz clazz, SourceDirAttribute sourceDirAttribute)68     public void visitSourceDirAttribute(Clazz clazz, SourceDirAttribute sourceDirAttribute)
69     {
70         attributeVisitor.visitSourceDirAttribute(clazz, sourceDirAttribute);
71     }
72 
73 
visitInnerClassesAttribute(Clazz clazz, InnerClassesAttribute innerClassesAttribute)74     public void visitInnerClassesAttribute(Clazz clazz, InnerClassesAttribute innerClassesAttribute)
75     {
76         attributeVisitor.visitInnerClassesAttribute(clazz, innerClassesAttribute);
77     }
78 
79 
visitEnclosingMethodAttribute(Clazz clazz, EnclosingMethodAttribute enclosingMethodAttribute)80     public void visitEnclosingMethodAttribute(Clazz clazz, EnclosingMethodAttribute enclosingMethodAttribute)
81     {
82         attributeVisitor.visitEnclosingMethodAttribute(clazz, enclosingMethodAttribute);
83     }
84 
85 
visitDeprecatedAttribute(Clazz clazz, DeprecatedAttribute deprecatedAttribute)86     public void visitDeprecatedAttribute(Clazz clazz, DeprecatedAttribute deprecatedAttribute)
87     {
88         attributeVisitor.visitDeprecatedAttribute(clazz, deprecatedAttribute);
89     }
90 
91 
visitSyntheticAttribute(Clazz clazz, SyntheticAttribute syntheticAttribute)92     public void visitSyntheticAttribute(Clazz clazz, SyntheticAttribute syntheticAttribute)
93     {
94         attributeVisitor.visitSyntheticAttribute(clazz, syntheticAttribute);
95     }
96 
97 
visitSignatureAttribute(Clazz clazz, SignatureAttribute syntheticAttribute)98     public void visitSignatureAttribute(Clazz clazz, SignatureAttribute syntheticAttribute)
99     {
100         attributeVisitor.visitSignatureAttribute(clazz, syntheticAttribute);
101     }
102 
103 
visitDeprecatedAttribute(Clazz clazz, Field field, DeprecatedAttribute deprecatedAttribute)104     public void visitDeprecatedAttribute(Clazz clazz, Field field, DeprecatedAttribute deprecatedAttribute)
105     {
106         attributeVisitor.visitDeprecatedAttribute(clazz, field, deprecatedAttribute);
107     }
108 
109 
visitSyntheticAttribute(Clazz clazz, Field field, SyntheticAttribute syntheticAttribute)110     public void visitSyntheticAttribute(Clazz clazz, Field field, SyntheticAttribute syntheticAttribute)
111     {
112         attributeVisitor.visitSyntheticAttribute(clazz, field, syntheticAttribute);
113     }
114 
115 
visitSignatureAttribute(Clazz clazz, Field field, SignatureAttribute syntheticAttribute)116     public void visitSignatureAttribute(Clazz clazz, Field field, SignatureAttribute syntheticAttribute)
117     {
118         attributeVisitor.visitSignatureAttribute(clazz, field, syntheticAttribute);
119     }
120 
121 
visitDeprecatedAttribute(Clazz clazz, Method method, DeprecatedAttribute deprecatedAttribute)122     public void visitDeprecatedAttribute(Clazz clazz, Method method, DeprecatedAttribute deprecatedAttribute)
123     {
124         attributeVisitor.visitDeprecatedAttribute(clazz, method, deprecatedAttribute);
125     }
126 
127 
visitSyntheticAttribute(Clazz clazz, Method method, SyntheticAttribute syntheticAttribute)128     public void visitSyntheticAttribute(Clazz clazz, Method method, SyntheticAttribute syntheticAttribute)
129     {
130         attributeVisitor.visitSyntheticAttribute(clazz, method, syntheticAttribute);
131     }
132 
133 
visitSignatureAttribute(Clazz clazz, Method method, SignatureAttribute syntheticAttribute)134     public void visitSignatureAttribute(Clazz clazz, Method method, SignatureAttribute syntheticAttribute)
135     {
136         attributeVisitor.visitSignatureAttribute(clazz, method, syntheticAttribute);
137     }
138 
139 
visitConstantValueAttribute(Clazz clazz, Field field, ConstantValueAttribute constantValueAttribute)140     public void visitConstantValueAttribute(Clazz clazz, Field field, ConstantValueAttribute constantValueAttribute)
141     {
142         attributeVisitor.visitConstantValueAttribute(clazz, field, constantValueAttribute);
143     }
144 
145 
visitMethodParametersAttribute(Clazz clazz, Method method, MethodParametersAttribute exceptionsAttribute)146     public void visitMethodParametersAttribute(Clazz clazz, Method method, MethodParametersAttribute exceptionsAttribute)
147     {
148         attributeVisitor.visitMethodParametersAttribute(clazz, method, exceptionsAttribute);
149     }
150 
151 
visitExceptionsAttribute(Clazz clazz, Method method, ExceptionsAttribute exceptionsAttribute)152     public void visitExceptionsAttribute(Clazz clazz, Method method, ExceptionsAttribute exceptionsAttribute)
153     {
154         attributeVisitor.visitExceptionsAttribute(clazz, method, exceptionsAttribute);
155     }
156 
157 
visitStackMapAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, StackMapAttribute stackMapAttribute)158     public void visitStackMapAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, StackMapAttribute stackMapAttribute)
159     {
160         attributeVisitor.visitStackMapAttribute(clazz, method, codeAttribute, stackMapAttribute);
161     }
162 
163 
visitStackMapTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, StackMapTableAttribute stackMapTableAttribute)164     public void visitStackMapTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, StackMapTableAttribute stackMapTableAttribute)
165     {
166         attributeVisitor.visitStackMapTableAttribute(clazz, method, codeAttribute, stackMapTableAttribute);
167     }
168 
169 
visitLineNumberTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LineNumberTableAttribute lineNumberTableAttribute)170     public void visitLineNumberTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LineNumberTableAttribute lineNumberTableAttribute)
171     {
172         attributeVisitor.visitLineNumberTableAttribute(clazz, method, codeAttribute, lineNumberTableAttribute);
173     }
174 
175 
visitLocalVariableTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTableAttribute localVariableTableAttribute)176     public void visitLocalVariableTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTableAttribute localVariableTableAttribute)
177     {
178         attributeVisitor.visitLocalVariableTableAttribute(clazz, method, codeAttribute, localVariableTableAttribute);
179     }
180 
181 
visitLocalVariableTypeTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTypeTableAttribute localVariableTypeTableAttribute)182     public void visitLocalVariableTypeTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTypeTableAttribute localVariableTypeTableAttribute)
183     {
184         attributeVisitor.visitLocalVariableTypeTableAttribute(clazz, method, codeAttribute, localVariableTypeTableAttribute);
185     }
186 
187 
visitRuntimeVisibleAnnotationsAttribute(Clazz clazz, RuntimeVisibleAnnotationsAttribute runtimeVisibleAnnotationsAttribute)188     public void visitRuntimeVisibleAnnotationsAttribute(Clazz clazz, RuntimeVisibleAnnotationsAttribute runtimeVisibleAnnotationsAttribute)
189     {
190         attributeVisitor.visitRuntimeVisibleAnnotationsAttribute(clazz, runtimeVisibleAnnotationsAttribute);
191     }
192 
193 
visitRuntimeInvisibleAnnotationsAttribute(Clazz clazz, RuntimeInvisibleAnnotationsAttribute runtimeInvisibleAnnotationsAttribute)194     public void visitRuntimeInvisibleAnnotationsAttribute(Clazz clazz, RuntimeInvisibleAnnotationsAttribute runtimeInvisibleAnnotationsAttribute)
195     {
196         attributeVisitor.visitRuntimeInvisibleAnnotationsAttribute(clazz, runtimeInvisibleAnnotationsAttribute);
197     }
198 
199 
visitRuntimeVisibleAnnotationsAttribute(Clazz clazz, Field field, RuntimeVisibleAnnotationsAttribute runtimeVisibleAnnotationsAttribute)200     public void visitRuntimeVisibleAnnotationsAttribute(Clazz clazz, Field field, RuntimeVisibleAnnotationsAttribute runtimeVisibleAnnotationsAttribute)
201     {
202         attributeVisitor.visitRuntimeVisibleAnnotationsAttribute(clazz, field, runtimeVisibleAnnotationsAttribute);
203     }
204 
205 
visitRuntimeInvisibleAnnotationsAttribute(Clazz clazz, Field field, RuntimeInvisibleAnnotationsAttribute runtimeInvisibleAnnotationsAttribute)206     public void visitRuntimeInvisibleAnnotationsAttribute(Clazz clazz, Field field, RuntimeInvisibleAnnotationsAttribute runtimeInvisibleAnnotationsAttribute)
207     {
208         attributeVisitor.visitRuntimeInvisibleAnnotationsAttribute(clazz, field, runtimeInvisibleAnnotationsAttribute);
209     }
210 
211 
visitRuntimeVisibleAnnotationsAttribute(Clazz clazz, Method method, RuntimeVisibleAnnotationsAttribute runtimeVisibleAnnotationsAttribute)212     public void visitRuntimeVisibleAnnotationsAttribute(Clazz clazz, Method method, RuntimeVisibleAnnotationsAttribute runtimeVisibleAnnotationsAttribute)
213     {
214         attributeVisitor.visitRuntimeVisibleAnnotationsAttribute(clazz, method, runtimeVisibleAnnotationsAttribute);
215     }
216 
217 
visitRuntimeInvisibleAnnotationsAttribute(Clazz clazz, Method method, RuntimeInvisibleAnnotationsAttribute runtimeInvisibleAnnotationsAttribute)218     public void visitRuntimeInvisibleAnnotationsAttribute(Clazz clazz, Method method, RuntimeInvisibleAnnotationsAttribute runtimeInvisibleAnnotationsAttribute)
219     {
220         attributeVisitor.visitRuntimeInvisibleAnnotationsAttribute(clazz, method, runtimeInvisibleAnnotationsAttribute);
221     }
222 
223 
visitRuntimeVisibleParameterAnnotationsAttribute(Clazz clazz, Method method, RuntimeVisibleParameterAnnotationsAttribute runtimeVisibleParameterAnnotationsAttribute)224     public void visitRuntimeVisibleParameterAnnotationsAttribute(Clazz clazz, Method method, RuntimeVisibleParameterAnnotationsAttribute runtimeVisibleParameterAnnotationsAttribute)
225     {
226         attributeVisitor.visitRuntimeVisibleParameterAnnotationsAttribute(clazz, method, runtimeVisibleParameterAnnotationsAttribute);
227     }
228 
229 
visitRuntimeInvisibleParameterAnnotationsAttribute(Clazz clazz, Method method, RuntimeInvisibleParameterAnnotationsAttribute runtimeInvisibleParameterAnnotationsAttribute)230     public void visitRuntimeInvisibleParameterAnnotationsAttribute(Clazz clazz, Method method, RuntimeInvisibleParameterAnnotationsAttribute runtimeInvisibleParameterAnnotationsAttribute)
231     {
232         attributeVisitor.visitRuntimeInvisibleParameterAnnotationsAttribute(clazz, method, runtimeInvisibleParameterAnnotationsAttribute);
233     }
234 
235 
visitRuntimeVisibleTypeAnnotationsAttribute(Clazz clazz, RuntimeVisibleTypeAnnotationsAttribute runtimeVisibleTypeAnnotationsAttribute)236     public void visitRuntimeVisibleTypeAnnotationsAttribute(Clazz clazz, RuntimeVisibleTypeAnnotationsAttribute runtimeVisibleTypeAnnotationsAttribute)
237     {
238         attributeVisitor.visitRuntimeVisibleTypeAnnotationsAttribute(clazz, runtimeVisibleTypeAnnotationsAttribute);
239     }
240 
241 
visitRuntimeVisibleTypeAnnotationsAttribute(Clazz clazz, Field field, RuntimeVisibleTypeAnnotationsAttribute runtimeVisibleTypeAnnotationsAttribute)242     public void visitRuntimeVisibleTypeAnnotationsAttribute(Clazz clazz, Field field, RuntimeVisibleTypeAnnotationsAttribute runtimeVisibleTypeAnnotationsAttribute)
243     {
244         attributeVisitor.visitRuntimeVisibleTypeAnnotationsAttribute(clazz, field, runtimeVisibleTypeAnnotationsAttribute);
245     }
246 
247 
visitRuntimeVisibleTypeAnnotationsAttribute(Clazz clazz, Method method, RuntimeVisibleTypeAnnotationsAttribute runtimeVisibleTypeAnnotationsAttribute)248     public void visitRuntimeVisibleTypeAnnotationsAttribute(Clazz clazz, Method method, RuntimeVisibleTypeAnnotationsAttribute runtimeVisibleTypeAnnotationsAttribute)
249     {
250         attributeVisitor.visitRuntimeVisibleTypeAnnotationsAttribute(clazz, method, runtimeVisibleTypeAnnotationsAttribute);
251     }
252 
253 
visitRuntimeVisibleTypeAnnotationsAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, RuntimeVisibleTypeAnnotationsAttribute runtimeVisibleTypeAnnotationsAttribute)254     public void visitRuntimeVisibleTypeAnnotationsAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, RuntimeVisibleTypeAnnotationsAttribute runtimeVisibleTypeAnnotationsAttribute)
255     {
256         attributeVisitor.visitRuntimeVisibleTypeAnnotationsAttribute(clazz, method, codeAttribute, runtimeVisibleTypeAnnotationsAttribute);
257     }
258 
259 
visitRuntimeInvisibleTypeAnnotationsAttribute(Clazz clazz, RuntimeInvisibleTypeAnnotationsAttribute runtimeInvisibleTypeAnnotationsAttribute)260     public void visitRuntimeInvisibleTypeAnnotationsAttribute(Clazz clazz, RuntimeInvisibleTypeAnnotationsAttribute runtimeInvisibleTypeAnnotationsAttribute)
261     {
262         attributeVisitor.visitRuntimeInvisibleTypeAnnotationsAttribute(clazz, runtimeInvisibleTypeAnnotationsAttribute);
263     }
264 
265 
visitRuntimeInvisibleTypeAnnotationsAttribute(Clazz clazz, Field field, RuntimeInvisibleTypeAnnotationsAttribute runtimeInvisibleTypeAnnotationsAttribute)266     public void visitRuntimeInvisibleTypeAnnotationsAttribute(Clazz clazz, Field field, RuntimeInvisibleTypeAnnotationsAttribute runtimeInvisibleTypeAnnotationsAttribute)
267     {
268         attributeVisitor.visitRuntimeInvisibleTypeAnnotationsAttribute(clazz, field, runtimeInvisibleTypeAnnotationsAttribute);
269     }
270 
271 
visitRuntimeInvisibleTypeAnnotationsAttribute(Clazz clazz, Method method, RuntimeInvisibleTypeAnnotationsAttribute runtimeInvisibleTypeAnnotationsAttribute)272     public void visitRuntimeInvisibleTypeAnnotationsAttribute(Clazz clazz, Method method, RuntimeInvisibleTypeAnnotationsAttribute runtimeInvisibleTypeAnnotationsAttribute)
273     {
274         attributeVisitor.visitRuntimeInvisibleTypeAnnotationsAttribute(clazz, method, runtimeInvisibleTypeAnnotationsAttribute);
275     }
276 
277 
visitRuntimeInvisibleTypeAnnotationsAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, RuntimeInvisibleTypeAnnotationsAttribute runtimeInvisibleTypeAnnotationsAttribute)278     public void visitRuntimeInvisibleTypeAnnotationsAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, RuntimeInvisibleTypeAnnotationsAttribute runtimeInvisibleTypeAnnotationsAttribute)
279     {
280         attributeVisitor.visitRuntimeInvisibleTypeAnnotationsAttribute(clazz, method, codeAttribute, runtimeInvisibleTypeAnnotationsAttribute);
281     }
282 
283 
visitAnnotationDefaultAttribute(Clazz clazz, Method method, AnnotationDefaultAttribute annotationDefaultAttribute)284     public void visitAnnotationDefaultAttribute(Clazz clazz, Method method, AnnotationDefaultAttribute annotationDefaultAttribute)
285     {
286         attributeVisitor.visitAnnotationDefaultAttribute(clazz, method, annotationDefaultAttribute);
287     }
288 
289 
visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute)290     public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute)
291     {
292         byte[] code    = codeAttribute.code;
293         byte[] oldCode = new byte[code.length];
294 
295         // Copy the current code.
296         System.arraycopy(code, 0, oldCode, 0, codeAttribute.u4codeLength);
297 
298         // Delegate to the real visitor.
299         attributeVisitor.visitCodeAttribute(clazz, method, codeAttribute);
300 
301         // Check if the code has changed.
302         if (codeHasChanged(codeAttribute, oldCode))
303         {
304             printChangedCode(clazz, method, codeAttribute, oldCode);
305         }
306     }
307 
308 
309     // Small utility methods.
310 
codeHasChanged(CodeAttribute codeAttribute, byte[] oldCode)311     private boolean codeHasChanged(CodeAttribute codeAttribute, byte[] oldCode)
312     {
313         if (oldCode.length != codeAttribute.u4codeLength)
314         {
315             return true;
316         }
317 
318         for (int index = 0; index < codeAttribute.u4codeLength; index++)
319         {
320             if (oldCode[index] != codeAttribute.code[index])
321             {
322                 return true;
323             }
324         }
325 
326         return false;
327     }
328 
329 
printChangedCode(Clazz clazz, Method method, CodeAttribute codeAttribute, byte[] oldCode)330     private void printChangedCode(Clazz         clazz,
331                                   Method        method,
332                                   CodeAttribute codeAttribute,
333                                   byte[]        oldCode)
334     {
335         System.out.println("Class "+ClassUtil.externalClassName(clazz.getName()));
336         System.out.println("Method "+ClassUtil.externalFullMethodDescription(clazz.getName(),
337                                                                              0,
338                                                                              method.getName(clazz),
339                                                                              method.getDescriptor(clazz)));
340 
341         for (int index = 0; index < codeAttribute.u4codeLength; index++)
342         {
343             System.out.println(
344                 (oldCode[index] == codeAttribute.code[index]? "  -- ":"  => ")+
345                 index+": "+
346                 Integer.toHexString(0x100|oldCode[index]           &0xff).substring(1)+" "+
347                 Integer.toHexString(0x100|codeAttribute.code[index]&0xff).substring(1));
348         }
349     }
350 }
351