1 /*
2  * Copyright (C) 2014 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 import org.objectweb.asm.*;
18 import org.objectweb.asm.tree.*;
19 import java.io.*;
20 import java.util.*;
21 
22 public class Asm {
23   /*
24 
25   Overall class access flags:
26 
27       0x0001 |  // public
28       0x0010 |  // final
29       0x0020 |  // super
30       0x0200 |  // interface
31       0x0400 |  // abstract
32       0x1000 |  // synthetic
33       0x2000 |  // annotation
34       0x4000 ;  // enum
35 
36   */
37 
38   public final static int INTERFACE_DEFINED_BITS =
39       0x0001 |  // public, may be set.
40       0x0010 |  // final, must not be set.
41       0x0020 |  // super, must not be set.
42       0x0200 |  // interface, must be set.
43       0x0400 |  // abstract, must be set.
44       0x1000 |  // synthetic, may be set.
45       0x2000 |  // annotation, may be set (annotation implies interface)
46       0x4000 ;  // enum, must not be set.
47 
48   public final static int CLASS_DEFINED_BITS =
49       0x0001 |  // public, may be set.
50       0x0010 |  // final, may be set.
51       0x0020 |  // super, may be set.
52       0x0200 |  // interface, must not be set.
53       0x0400 |  // abstract, may be set.
54       0x1000 |  // synthetic, may be set.
55       0x2000 |  // annotation, must not be set.
56       0x4000 ;  // enum, may be set.
57 
58   public final static int FIELD_DEFINED_BITS =
59        0x0001 |  // public
60        0x0002 |  // private
61        0x0004 |  // protected
62        0x0008 |  // static
63        0x0010 |  // final
64        0x0040 |  // volatile
65        0x0080 |  // transient
66        0x1000 |  // synthetic
67        0x4000 ;  // enum
68 
69   public final static int METHOD_DEFINED_BITS =
70        0x0001 |  // public
71        0x0002 |  // private
72        0x0004 |  // protected
73        0x0008 |  // static
74        0x0010 |  // final
75        0x0020 |  // synchronized
76        0x0040 |  // bridge
77        0x0080 |  // varargs
78        0x0100 |  // native
79        0x0400 |  // abstract
80        0x0800 |  // strictfp
81        0x1000 ;  // synthetic
82 
main(String args[])83   public static void main(String args[]) throws Exception {
84     modify("Inf");
85     modify("NonInf");
86   }
87 
modify(String clazz)88   private static void modify(String clazz) throws Exception {
89     ClassNode classNode = new ClassNode();
90     ClassReader cr = new ClassReader(clazz);
91     cr.accept(classNode, 0);
92 
93     modify(classNode);
94 
95     ClassWriter cw = new ClassWriter(0);
96     classNode.accept(cw);
97     byte[] b = cw.toByteArray();
98     OutputStream out = new FileOutputStream(clazz + ".out");
99     out.write(b, 0, b.length);
100     out.close();
101   }
102 
modify(ClassNode classNode)103   private static void modify(ClassNode classNode) throws Exception {
104     int classFlagsOr = 0xFFFF;
105     // Check whether classNode is an interface or class.
106     if ((classNode.access & Opcodes.ACC_INTERFACE) == 0) {
107       classFlagsOr ^= CLASS_DEFINED_BITS;
108     } else {
109       classFlagsOr ^= INTERFACE_DEFINED_BITS;
110     }
111     classNode.access |= classFlagsOr;
112 
113     // Fields.
114     int fieldFlagsOr = 0xFFFF ^ FIELD_DEFINED_BITS;
115     for (FieldNode fieldNode : (List<FieldNode>)classNode.fields) {
116       fieldNode.access |= fieldFlagsOr;
117     }
118 
119     // Methods.
120     int methodFlagsOr = 0xFFFF ^ METHOD_DEFINED_BITS;
121     for (MethodNode methodNode :(List<MethodNode>) classNode.methods) {
122       methodNode.access |= methodFlagsOr;
123     }
124   }
125 }
126