• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2021 Code Intelligence GmbH
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //      http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 package com.code_intelligence.jazzer.api;
16 
17 import java.lang.annotation.Documented;
18 import java.lang.annotation.ElementType;
19 import java.lang.annotation.Repeatable;
20 import java.lang.annotation.Retention;
21 import java.lang.annotation.RetentionPolicy;
22 import java.lang.annotation.Target;
23 import java.lang.invoke.MethodType;
24 
25 /**
26  * Registers this method as a hook that should run after the method
27  * specified by the annotation parameters has returned.
28  * <p>
29  * This method will be called after every call to the target method and has
30  * access to its return value. The target method is specified by
31  * {@link #targetClassName()} and {@link #targetMethod()}. In case of an
32  * overloaded method, {@link #targetMethodDescriptor()} can be used to restrict
33  * the application of the hook to a particular overload.
34  * <p>
35  * The signature of the annotated method must be as follows (this does not
36  * restrict the method name and parameter names, which are arbitrary),
37  * depending on the value of {@link #type()}:
38  *
39  * <dl>
40  * <dt><span class="strong">{@link HookType#BEFORE}</span>
41  * <dd>
42  * <pre>{@code
43  * public static void hook(MethodHandle method, Object thisObject, Object[] arguments, int hookId)
44  * }</pre>
45  * Arguments:
46  * <p><ul>
47  * <li>{@code method}: A {@link java.lang.invoke.MethodHandle} representing the
48  * original method. The original method can be invoked via
49  * {@link java.lang.invoke.MethodHandle#invokeWithArguments(Object...)}. This
50  * requires passing {@code thisObject} as the first argument if the method is
51  * not static. This argument can be {@code null}.
52  * <li>{@code thisObject}: An {@link Object} containing the implicit
53  * {@code this} argument to the original method. If the original method is
54  * static, this argument will be {@code null}.
55  * <li>{@code arguments}: An array of {@link Object}s containing the arguments
56  * passed to the original method. Primitive types (e.g. {@code boolean}) will be
57  * wrapped into their corresponding wrapper type (e.g. {@link Boolean}).
58  * <li>{@code hookId}: A random {@code int} identifying the particular call
59  * site.This can be used to derive additional coverage information.
60  * </ul>
61  *
62  * <dt><span class="strong">{@link HookType#REPLACE}</span>
63  * <dd>
64  * <pre>{@code
65  * public static Object hook(MethodHandle method, Object thisObject, Object[] arguments, int hookId)
66  * }</pre>
67  * The return type may alternatively be taken to be the exact return type of
68  * target method or a wrapper type thereof. The returned object will be casted
69  * and unwrapped automatically.
70  * <p>
71  * Arguments:
72  * <p><ul>
73  * <li>{@code method}: A {@link java.lang.invoke.MethodHandle} representing the
74  * original method. The original method can be invoked via
75  * {@link java.lang.invoke.MethodHandle#invokeWithArguments(Object...)}. This
76  * requires passing {@code thisObject} as the first argument if the method is
77  * not static. This argument can be {@code null}.
78  * <li>{@code thisObject}: An {@link Object} containing the implicit
79  * {@code this} argument to the original method. If the original method is
80  * static, this argument will be {@code null}.
81  * <li>{@code arguments}: An array of {@link Object}s containing the arguments
82  * passed to the original method. Primitive types (e.g. {@code boolean}) will be
83  * wrapped into their corresponding wrapper type (e.g. {@link Boolean}).
84  * <li>{@code hookId}: A random {@code int} identifying the particular call
85  * site.This can be used to derive additional coverage information.
86  * </ul><p>
87  * <p>
88  * Return value: the value that should take the role of the value the target
89  * method would have returned
90  *
91  * <dt><span class="strong">{@link HookType#AFTER}</span>
92  * <dd>
93  * <pre>{@code
94  * public static void hook(MethodHandle method, Object thisObject, Object[] arguments, int hookId,
95  * Object returnValue)
96  * }</pre>
97  * Arguments:
98  * <p><ul>
99  * <li>{@code method}: A {@link java.lang.invoke.MethodHandle} representing the
100  * original method. The original method can be invoked via
101  * {@link java.lang.invoke.MethodHandle#invokeWithArguments(Object...)}. This
102  * requires passing {@code thisObject} as the first argument if the method is
103  * not static. This argument can be {@code null}.
104  * <li>{@code thisObject}: An {@link Object} containing the implicit
105  * {@code this} argument to the original method. If the original method is
106  * static, this argument will be {@code null}.
107  * <li>{@code arguments}: An array of {@link Object}s containing the arguments
108  * passed to the original method. Primitive types (e.g. {@code boolean}) will be
109  * wrapped into their corresponding wrapper type (e.g. {@link Boolean}).
110  * <li>{@code hookId}: A random {@code int} identifying the particular call
111  * site.This can be used to derive additional coverage information.
112  * <li>{@code returnValue}: An {@link Object} containing the return value of the
113  * invocation of the original method. Primitive types (e.g. {@code boolean})
114  * will be wrapped into their corresponding wrapper type (e.g. {@link Boolean}).
115  * If the original method has return type {@code void}, this value will be
116  * {@code null}.
117  */
118 @Retention(RetentionPolicy.RUNTIME)
119 @Target(ElementType.METHOD)
120 @Repeatable(MethodHooks.class)
121 @Documented
122 public @interface MethodHook {
123   /**
124    * The time at which the annotated method should be called.
125    * <p>
126    * If this is {@link HookType#BEFORE}, the annotated method will be called
127    * before the target method and has access to its arguments.
128    * <p>
129    * If this is {@link HookType#REPLACE}, the annotated method will be called
130    * instead of the target method. It has access to its arguments and can
131    * return a value that will replace the target method's return value.
132    * <p>
133    * If this is {@link HookType#AFTER}, the annotated method will be called
134    * after the target method and has access to its arguments and return
135    * value.
136    *
137    * @return when the hook should be called
138    */
type()139   HookType type();
140 
141   /**
142    * The name of the class that contains the method that should be hooked,
143    * as returned by {@link Class#getName()}.
144    * <p>
145    * Examples:
146    * <p><ul>
147    * <li>{@link String}: {@code "java.lang.String"}
148    * <li>{@link java.nio.file.FileSystem}: {@code "java.nio.file.FileSystem"}
149    * </ul><p>
150    *
151    * @return the name of the class containing the method to be hooked
152    */
targetClassName()153   String targetClassName();
154 
155   /**
156    * The name of the method to be hooked. Use {@code "<init>"} for
157    * constructors.
158    * <p>
159    * Examples:
160    * <p><ul>
161    * <li>{@link String#equals(Object)}: {@code "equals"}
162    * <li>{@link String#String()}: {@code "<init>"}
163    * </ul><p>
164    *
165    * @return the name of the method to be hooked
166    */
targetMethod()167   String targetMethod();
168 
169   /**
170    * The descriptor of the method to be hooked. This is only needed if there
171    * are multiple methods with the same name and not all of them should be
172    * hooked.
173    * <p>
174    * The descriptor of a method is an internal representation of the method's
175    * signature, which includes the types of its parameters and its return
176    * value. For more information on descriptors, see the
177    * <a href=https://docs.oracle.com/javase/specs/jvms/se15/html/jvms-4.html#jvms-4.3.3>JVM
178    * Specification, Section 4.3.3</a> and {@link MethodType#toMethodDescriptorString()}
179    *
180    * @return the descriptor of the method to be hooked
181    */
targetMethodDescriptor()182   String targetMethodDescriptor() default "";
183 }
184