Path: blob/master/src/java.instrument/share/native/libinstrument/JPLISAgent.h
41149 views
/*1* Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425/*26* Copyright 2003 Wily Technology, Inc.27*/2829#ifndef _JPLISAGENT_H_30#define _JPLISAGENT_H_3132#include <jni.h>33#include <jvmti.h>3435#ifdef __cplusplus36extern "C" {37#endif3839/*40* The JPLISAgent manages the initialization all of the Java programming language Agents.41* It also supports the native method bridge between the JPLIS and the JVMTI.42* It maintains a single JVMTI Env that all JPL agents share.43* It parses command line requests and creates individual Java agents.44*/454647/*48* Forward definitions49*/50struct _JPLISAgent;5152typedef struct _JPLISAgent JPLISAgent;53typedef struct _JPLISEnvironment JPLISEnvironment;545556/* constants for class names and methods names and such57these all must stay in sync with Java code & interfaces58*/59#define JPLIS_INSTRUMENTIMPL_CLASSNAME "sun/instrument/InstrumentationImpl"60#define JPLIS_INSTRUMENTIMPL_CONSTRUCTOR_METHODNAME "<init>"61#define JPLIS_INSTRUMENTIMPL_CONSTRUCTOR_METHODSIGNATURE "(JZZ)V"62#define JPLIS_INSTRUMENTIMPL_PREMAININVOKER_METHODNAME "loadClassAndCallPremain"63#define JPLIS_INSTRUMENTIMPL_PREMAININVOKER_METHODSIGNATURE "(Ljava/lang/String;Ljava/lang/String;)V"64#define JPLIS_INSTRUMENTIMPL_AGENTMAININVOKER_METHODNAME "loadClassAndCallAgentmain"65#define JPLIS_INSTRUMENTIMPL_AGENTMAININVOKER_METHODSIGNATURE "(Ljava/lang/String;Ljava/lang/String;)V"66#define JPLIS_INSTRUMENTIMPL_TRANSFORM_METHODNAME "transform"67#define JPLIS_INSTRUMENTIMPL_TRANSFORM_METHODSIGNATURE \68"(Ljava/lang/Module;Ljava/lang/ClassLoader;Ljava/lang/String;Ljava/lang/Class;Ljava/security/ProtectionDomain;[BZ)[B"697071/*72* Error messages73*/74#define JPLIS_ERRORMESSAGE_CANNOTSTART "processing of -javaagent failed"757677/*78* Our initialization errors79*/80typedef enum {81JPLIS_INIT_ERROR_NONE,82JPLIS_INIT_ERROR_CANNOT_CREATE_NATIVE_AGENT,83JPLIS_INIT_ERROR_FAILURE,84JPLIS_INIT_ERROR_ALLOCATION_FAILURE,85JPLIS_INIT_ERROR_AGENT_CLASS_NOT_SPECIFIED86} JPLISInitializationError;878889struct _JPLISEnvironment {90jvmtiEnv * mJVMTIEnv; /* the JVM TI environment */91JPLISAgent * mAgent; /* corresponding agent */92jboolean mIsRetransformer; /* indicates if special environment */93};9495struct _JPLISAgent {96JavaVM * mJVM; /* handle to the JVM */97JPLISEnvironment mNormalEnvironment; /* for every thing but retransform stuff */98JPLISEnvironment mRetransformEnvironment;/* for retransform stuff only */99jobject mInstrumentationImpl; /* handle to the Instrumentation instance */100jmethodID mPremainCaller; /* method on the InstrumentationImpl that does the premain stuff (cached to save lots of lookups) */101jmethodID mAgentmainCaller; /* method on the InstrumentationImpl for agents loaded via attach mechanism */102jmethodID mTransform; /* method on the InstrumentationImpl that does the class file transform */103jboolean mRedefineAvailable; /* cached answer to "does this agent support redefine" */104jboolean mRedefineAdded; /* indicates if can_redefine_classes capability has been added */105jboolean mNativeMethodPrefixAvailable; /* cached answer to "does this agent support prefixing" */106jboolean mNativeMethodPrefixAdded; /* indicates if can_set_native_method_prefix capability has been added */107char const * mAgentClassName; /* agent class name */108char const * mOptionsString; /* -javaagent options string */109const char * mJarfile; /* agent jar file name */110};111112/*113* JVMTI event handlers114*/115116/* VMInit event handler. Installed during OnLoad, then removed during VMInit. */117extern void JNICALL118eventHandlerVMInit( jvmtiEnv * jvmtienv,119JNIEnv * jnienv,120jthread thread);121122/*123* ClassFileLoadHook event handler.124* Enabled when the first transformer is added;125* Disabled when the last transformer is removed.126*/127extern void JNICALL128eventHandlerClassFileLoadHook( jvmtiEnv * jvmtienv,129JNIEnv * jnienv,130jclass class_being_redefined,131jobject loader,132const char* name,133jobject protectionDomain,134jint class_data_len,135const unsigned char* class_data,136jint* new_class_data_len,137unsigned char** new_class_data);138139/*140* Main entry points for the JPLIS JVMTI agent code141*/142143/* looks up the environment instance. returns null if there isn't one */144extern JPLISEnvironment *145getJPLISEnvironment(jvmtiEnv * jvmtienv);146147/* Creates a new JPLIS agent.148* Returns error if the agent cannot be created and initialized.149* The JPLISAgent* pointed to by agent_ptr is set to the new broker,150* or NULL if an error has occurred.151*/152extern JPLISInitializationError153createNewJPLISAgent(JavaVM * vm, JPLISAgent **agent_ptr);154155/* Adds can_redefine_classes capability */156extern void157addRedefineClassesCapability(JPLISAgent * agent);158159/* Add the can_set_native_method_prefix capability */160extern void161addNativeMethodPrefixCapability(JPLISAgent * agent);162163/* Add the can_maintain_original_method_order capability (for testing) */164extern void165addOriginalMethodOrderCapability(JPLISAgent * agent);166167168/* Our JPLIS agent is paralleled by a Java InstrumentationImpl instance.169* This routine uses JNI to create and initialized the Java instance.170* Returns true if it succeeds, false otherwise.171*/172extern jboolean173createInstrumentationImpl( JNIEnv * jnienv,174JPLISAgent * agent);175176177/* during OnLoad phase (command line parsing)178* record the parameters of -javaagent179*/180extern JPLISInitializationError181recordCommandLineData( JPLISAgent * agent,182const char * agentClass,183const char * optionsString );184185/* Swaps the start phase event handlers out and the live phase event handlers in.186* Also used in attach to enabled live phase event handlers.187* Returns true if it succeeds, false otherwise.188*/189extern jboolean190setLivePhaseEventHandlers( JPLISAgent * agent);191192/* Loads the Java agent according to the already processed command line. For each,193* loads the Java agent class, then calls the premain method.194* Returns true if all Java agent classes are loaded and all premain methods complete with no exceptions,195* false otherwise.196*/197extern jboolean198startJavaAgent( JPLISAgent * agent,199JNIEnv * jnienv,200const char * classname,201const char * optionsString,202jmethodID agentMainMethod);203204205/* during VMInit processing206* this is how the invocation engine (callback wrapper) tells us to start up all the javaagents207*/208extern jboolean209processJavaStart( JPLISAgent * agent,210JNIEnv * jnienv);211212/* on an ongoing basis,213* this is how the invocation engine (callback wrapper) tells us to process a class file214*/215extern void216transformClassFile( JPLISAgent * agent,217JNIEnv * jnienv,218jobject loader,219const char* name,220jclass classBeingRedefined,221jobject protectionDomain,222jint class_data_len,223const unsigned char* class_data,224jint* new_class_data_len,225unsigned char** new_class_data,226jboolean is_retransformer);227228/* on an ongoing basis,229* Return the environment with the retransformation capability.230* Create it if it doesn't exist.231*/232extern jvmtiEnv *233retransformableEnvironment(JPLISAgent * agent);234235/* on an ongoing basis,236* these are implementations of the Instrumentation services.237* Most are simple covers for JVMTI access services. These are the guts of the InstrumentationImpl238* native methods.239*/240extern jboolean241isModifiableClass(JNIEnv * jnienv, JPLISAgent * agent, jclass clazz);242243extern jboolean244isRetransformClassesSupported(JNIEnv * jnienv, JPLISAgent * agent);245246extern void247setHasTransformers(JNIEnv * jnienv, JPLISAgent * agent, jboolean has);248249extern void250setHasRetransformableTransformers(JNIEnv * jnienv, JPLISAgent * agent, jboolean has);251252extern void253retransformClasses(JNIEnv * jnienv, JPLISAgent * agent, jobjectArray classes);254255extern void256redefineClasses(JNIEnv * jnienv, JPLISAgent * agent, jobjectArray classDefinitions);257258extern jobjectArray259getAllLoadedClasses(JNIEnv * jnienv, JPLISAgent * agent);260261extern jobjectArray262getInitiatedClasses(JNIEnv * jnienv, JPLISAgent * agent, jobject classLoader);263264extern jlong265getObjectSize(JNIEnv * jnienv, JPLISAgent * agent, jobject objectToSize);266267extern void268appendToClassLoaderSearch(JNIEnv * jnienv, JPLISAgent * agent, jstring jarFile, jboolean isBootLoader);269270extern void271setNativeMethodPrefixes(JNIEnv * jnienv, JPLISAgent * agent, jobjectArray prefixArray,272jboolean isRetransformable);273274#define jvmti(a) a->mNormalEnvironment.mJVMTIEnv275276/*277* A set of macros for insulating the JLI method callers from278* JVMTI_ERROR_WRONG_PHASE return codes.279*/280281/* for a JLI method where "blob" is executed before simply returning */282#define check_phase_blob_ret(ret, blob) \283if ((ret) == JVMTI_ERROR_WRONG_PHASE) { \284blob; \285return; \286}287288/* for a JLI method where simply returning is benign */289#define check_phase_ret(ret) \290if ((ret) == JVMTI_ERROR_WRONG_PHASE) { \291return; \292}293294/* for a JLI method where returning zero (0) is benign */295#define check_phase_ret_0(ret) \296if ((ret) == JVMTI_ERROR_WRONG_PHASE) { \297return 0; \298}299300/* for a JLI method where returning one (1) is benign */301#define check_phase_ret_1(ret) \302if ((ret) == JVMTI_ERROR_WRONG_PHASE) { \303return 1; \304}305306/* for a case where a specific "blob" must be returned */307#define check_phase_ret_blob(ret, blob) \308if ((ret) == JVMTI_ERROR_WRONG_PHASE) { \309return (blob); \310}311312/* for a JLI method where returning false is benign */313#define check_phase_ret_false(ret) \314if ((ret) == JVMTI_ERROR_WRONG_PHASE) { \315return (jboolean) 0; \316}317318#ifdef __cplusplus319} /* extern "C" */320#endif /* __cplusplus */321322323#endif324325326