1 /* 2 * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 /* 27 * Copyright 2003 Wily Technology, Inc. 28 */ 29 30 #ifndef _JPLISAGENT_H_ 31 #define _JPLISAGENT_H_ 32 33 #include <jni.h> 34 #include <jvmti.h> 35 36 #ifdef __cplusplus 37 extern "C" { 38 #endif 39 40 /* 41 * The JPLISAgent manages the initialization all of the Java programming language Agents. 42 * It also supports the native method bridge between the JPLIS and the JVMTI. 43 * It maintains a single JVMTI Env that all JPL agents share. 44 * It parses command line requests and creates individual Java agents. 45 */ 46 47 48 /* 49 * Forward definitions 50 */ 51 struct _JPLISAgent; 52 53 typedef struct _JPLISAgent JPLISAgent; 54 typedef struct _JPLISEnvironment JPLISEnvironment; 55 56 57 /* constants for class names and methods names and such 58 these all must stay in sync with Java code & interfaces 59 */ 60 #define JPLIS_INSTRUMENTIMPL_CLASSNAME "sun/instrument/InstrumentationImpl" 61 #define JPLIS_INSTRUMENTIMPL_CONSTRUCTOR_METHODNAME "<init>" 62 #define JPLIS_INSTRUMENTIMPL_CONSTRUCTOR_METHODSIGNATURE "(JZZ)V" 63 #define JPLIS_INSTRUMENTIMPL_PREMAININVOKER_METHODNAME "loadClassAndCallPremain" 64 #define JPLIS_INSTRUMENTIMPL_PREMAININVOKER_METHODSIGNATURE "(Ljava/lang/String;Ljava/lang/String;)V" 65 #define JPLIS_INSTRUMENTIMPL_AGENTMAININVOKER_METHODNAME "loadClassAndCallAgentmain" 66 #define JPLIS_INSTRUMENTIMPL_AGENTMAININVOKER_METHODSIGNATURE "(Ljava/lang/String;Ljava/lang/String;)V" 67 #define JPLIS_INSTRUMENTIMPL_TRANSFORM_METHODNAME "transform" 68 #define JPLIS_INSTRUMENTIMPL_TRANSFORM_METHODSIGNATURE \ 69 "(Ljava/lang/Module;Ljava/lang/ClassLoader;Ljava/lang/String;Ljava/lang/Class;Ljava/security/ProtectionDomain;[BZ)[B" 70 71 72 /* 73 * Error messages 74 */ 75 #define JPLIS_ERRORMESSAGE_CANNOTSTART "processing of -javaagent failed" 76 77 78 /* 79 * Our initialization errors 80 */ 81 typedef enum { 82 JPLIS_INIT_ERROR_NONE, 83 JPLIS_INIT_ERROR_CANNOT_CREATE_NATIVE_AGENT, 84 JPLIS_INIT_ERROR_FAILURE, 85 JPLIS_INIT_ERROR_ALLOCATION_FAILURE, 86 JPLIS_INIT_ERROR_AGENT_CLASS_NOT_SPECIFIED 87 } JPLISInitializationError; 88 89 90 struct _JPLISEnvironment { 91 jvmtiEnv * mJVMTIEnv; /* the JVM TI environment */ 92 JPLISAgent * mAgent; /* corresponding agent */ 93 jboolean mIsRetransformer; /* indicates if special environment */ 94 }; 95 96 struct _JPLISAgent { 97 JavaVM * mJVM; /* handle to the JVM */ 98 JPLISEnvironment mNormalEnvironment; /* for every thing but retransform stuff */ 99 JPLISEnvironment mRetransformEnvironment;/* for retransform stuff only */ 100 jobject mInstrumentationImpl; /* handle to the Instrumentation instance */ 101 jmethodID mPremainCaller; /* method on the InstrumentationImpl that does the premain stuff (cached to save lots of lookups) */ 102 jmethodID mAgentmainCaller; /* method on the InstrumentationImpl for agents loaded via attach mechanism */ 103 jmethodID mTransform; /* method on the InstrumentationImpl that does the class file transform */ 104 jboolean mRedefineAvailable; /* cached answer to "does this agent support redefine" */ 105 jboolean mRedefineAdded; /* indicates if can_redefine_classes capability has been added */ 106 jboolean mNativeMethodPrefixAvailable; /* cached answer to "does this agent support prefixing" */ 107 jboolean mNativeMethodPrefixAdded; /* indicates if can_set_native_method_prefix capability has been added */ 108 char const * mAgentClassName; /* agent class name */ 109 char const * mOptionsString; /* -javaagent options string */ 110 const char * mJarfile; /* agent jar file name */ 111 }; 112 113 /* 114 * JVMTI event handlers 115 */ 116 117 /* VMInit event handler. Installed during OnLoad, then removed during VMInit. */ 118 extern void JNICALL 119 eventHandlerVMInit( jvmtiEnv * jvmtienv, 120 JNIEnv * jnienv, 121 jthread thread); 122 123 /* 124 * ClassFileLoadHook event handler. 125 * Enabled when the first transformer is added; 126 * Disabled when the last transformer is removed. 127 */ 128 extern void JNICALL 129 eventHandlerClassFileLoadHook( jvmtiEnv * jvmtienv, 130 JNIEnv * jnienv, 131 jclass class_being_redefined, 132 jobject loader, 133 const char* name, 134 jobject protectionDomain, 135 jint class_data_len, 136 const unsigned char* class_data, 137 jint* new_class_data_len, 138 unsigned char** new_class_data); 139 140 /* 141 * Main entry points for the JPLIS JVMTI agent code 142 */ 143 144 /* looks up the environment instance. returns null if there isn't one */ 145 extern JPLISEnvironment * 146 getJPLISEnvironment(jvmtiEnv * jvmtienv); 147 148 /* Creates a new JPLIS agent. 149 * Returns error if the agent cannot be created and initialized. 150 * The JPLISAgent* pointed to by agent_ptr is set to the new broker, 151 * or NULL if an error has occurred. 152 */ 153 extern JPLISInitializationError 154 createNewJPLISAgent(JavaVM * vm, JPLISAgent **agent_ptr); 155 156 /* Adds can_redefine_classes capability */ 157 extern void 158 addRedefineClassesCapability(JPLISAgent * agent); 159 160 /* Add the can_set_native_method_prefix capability */ 161 extern void 162 addNativeMethodPrefixCapability(JPLISAgent * agent); 163 164 /* Add the can_maintain_original_method_order capability (for testing) */ 165 extern void 166 addOriginalMethodOrderCapability(JPLISAgent * agent); 167 168 169 /* Our JPLIS agent is paralleled by a Java InstrumentationImpl instance. 170 * This routine uses JNI to create and initialized the Java instance. 171 * Returns true if it succeeds, false otherwise. 172 */ 173 extern jboolean 174 createInstrumentationImpl( JNIEnv * jnienv, 175 JPLISAgent * agent); 176 177 178 /* during OnLoad phase (command line parsing) 179 * record the parameters of -javaagent 180 */ 181 extern JPLISInitializationError 182 recordCommandLineData( JPLISAgent * agent, 183 const char * agentClass, 184 const char * optionsString ); 185 186 /* Swaps the start phase event handlers out and the live phase event handlers in. 187 * Also used in attach to enabled live phase event handlers. 188 * Returns true if it succeeds, false otherwise. 189 */ 190 extern jboolean 191 setLivePhaseEventHandlers( JPLISAgent * agent); 192 193 /* Loads the Java agent according to the already processed command line. For each, 194 * loads the Java agent class, then calls the premain method. 195 * Returns true if all Java agent classes are loaded and all premain methods complete with no exceptions, 196 * false otherwise. 197 */ 198 extern jboolean 199 startJavaAgent( JPLISAgent * agent, 200 JNIEnv * jnienv, 201 const char * classname, 202 const char * optionsString, 203 jmethodID agentMainMethod); 204 205 206 /* during VMInit processing 207 * this is how the invocation engine (callback wrapper) tells us to start up all the javaagents 208 */ 209 extern jboolean 210 processJavaStart( JPLISAgent * agent, 211 JNIEnv * jnienv); 212 213 /* on an ongoing basis, 214 * this is how the invocation engine (callback wrapper) tells us to process a class file 215 */ 216 extern void 217 transformClassFile( JPLISAgent * agent, 218 JNIEnv * jnienv, 219 jobject loader, 220 const char* name, 221 jclass classBeingRedefined, 222 jobject protectionDomain, 223 jint class_data_len, 224 const unsigned char* class_data, 225 jint* new_class_data_len, 226 unsigned char** new_class_data, 227 jboolean is_retransformer); 228 229 /* on an ongoing basis, 230 * Return the environment with the retransformation capability. 231 * Create it if it doesn't exist. 232 */ 233 extern jvmtiEnv * 234 retransformableEnvironment(JPLISAgent * agent); 235 236 /* on an ongoing basis, 237 * these are implementations of the Instrumentation services. 238 * Most are simple covers for JVMTI access services. These are the guts of the InstrumentationImpl 239 * native methods. 240 */ 241 extern jboolean 242 isModifiableClass(JNIEnv * jnienv, JPLISAgent * agent, jclass clazz); 243 244 extern jboolean 245 isRetransformClassesSupported(JNIEnv * jnienv, JPLISAgent * agent); 246 247 extern void 248 setHasTransformers(JNIEnv * jnienv, JPLISAgent * agent, jboolean has); 249 250 extern void 251 setHasRetransformableTransformers(JNIEnv * jnienv, JPLISAgent * agent, jboolean has); 252 253 extern void 254 retransformClasses(JNIEnv * jnienv, JPLISAgent * agent, jobjectArray classes); 255 256 extern void 257 redefineClasses(JNIEnv * jnienv, JPLISAgent * agent, jobjectArray classDefinitions); 258 259 extern jobjectArray 260 getAllLoadedClasses(JNIEnv * jnienv, JPLISAgent * agent); 261 262 extern jobjectArray 263 getInitiatedClasses(JNIEnv * jnienv, JPLISAgent * agent, jobject classLoader); 264 265 extern jlong 266 getObjectSize(JNIEnv * jnienv, JPLISAgent * agent, jobject objectToSize); 267 268 extern void 269 appendToClassLoaderSearch(JNIEnv * jnienv, JPLISAgent * agent, jstring jarFile, jboolean isBootLoader); 270 271 extern void 272 setNativeMethodPrefixes(JNIEnv * jnienv, JPLISAgent * agent, jobjectArray prefixArray, 273 jboolean isRetransformable); 274 275 #define jvmti(a) a->mNormalEnvironment.mJVMTIEnv 276 277 /* 278 * A set of macros for insulating the JLI method callers from 279 * JVMTI_ERROR_WRONG_PHASE return codes. 280 */ 281 282 /* for a JLI method where "blob" is executed before simply returning */ 283 #define check_phase_blob_ret(ret, blob) \ 284 if ((ret) == JVMTI_ERROR_WRONG_PHASE) { \ 285 blob; \ 286 return; \ 287 } 288 289 /* for a JLI method where simply returning is benign */ 290 #define check_phase_ret(ret) \ 291 if ((ret) == JVMTI_ERROR_WRONG_PHASE) { \ 292 return; \ 293 } 294 295 /* for a JLI method where returning zero (0) is benign */ 296 #define check_phase_ret_0(ret) \ 297 if ((ret) == JVMTI_ERROR_WRONG_PHASE) { \ 298 return 0; \ 299 } 300 301 /* for a JLI method where returning one (1) is benign */ 302 #define check_phase_ret_1(ret) \ 303 if ((ret) == JVMTI_ERROR_WRONG_PHASE) { \ 304 return 1; \ 305 } 306 307 /* for a case where a specific "blob" must be returned */ 308 #define check_phase_ret_blob(ret, blob) \ 309 if ((ret) == JVMTI_ERROR_WRONG_PHASE) { \ 310 return (blob); \ 311 } 312 313 /* for a JLI method where returning false is benign */ 314 #define check_phase_ret_false(ret) \ 315 if ((ret) == JVMTI_ERROR_WRONG_PHASE) { \ 316 return (jboolean) 0; \ 317 } 318 319 #ifdef __cplusplus 320 } /* extern "C" */ 321 #endif /* __cplusplus */ 322 323 324 #endif 325