7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24 #include <string.h>
25 #include "jvmti.h"
26 #include "agent_common.h"
27 #include "jni_tools.h"
28 #include "jvmti_tools.h"
29
30 extern "C" {
31
32 /* scaffold objects */
33 static jvmtiEnv *jvmti = NULL;
34 static jlong timeout = 0;
35
36 #define TESTED_CLASS_NAME "nsk/jvmti/scenarios/bcinstr/BI01/bi01t001a"
37
38 static jint newClassSize;
39 static unsigned char* newClassBytes;
40 static jvmtiClassDefinition oldClassDef;
41
42 /* ============================================================================= */
43 /*
44 * Class: nsk_jvmti_scenarios_bcinstr_BI01_bi01t001
45 * Method: setNewByteCode
46 * Signature: ([B)Z
47 */
48 JNIEXPORT jboolean JNICALL
49 Java_nsk_jvmti_scenarios_bcinstr_BI01_bi01t001_setNewByteCode(JNIEnv *jni_env,
50 jobject o, jbyteArray byteCode) {
51
52 jbyte* elements;
53 jboolean isCopy;
54
55 newClassSize = jni_env->GetArrayLength(byteCode);
56 if (!NSK_JNI_VERIFY(jni_env, newClassSize > 0)) {
57 nsk_jvmti_setFailStatus();
58 return NSK_FALSE;
59 }
60 NSK_DISPLAY1("\t... got array size: %d\n", newClassSize);
61
62 elements = jni_env->GetByteArrayElements(byteCode, &isCopy);
63 if (!NSK_JNI_VERIFY(jni_env, elements != NULL)) {
64 nsk_jvmti_setFailStatus();
65 return NSK_FALSE;
66 }
67 NSK_DISPLAY1("\t... got elements list: 0x%p\n", (void*)elements);
68
69 if (!NSK_JVMTI_VERIFY(jvmti->Allocate(newClassSize, &newClassBytes))) {
70 nsk_jvmti_setFailStatus();
71 return NSK_FALSE;
72 }
73 NSK_DISPLAY1("\t... created bytes array: 0x%p\n", (void*)newClassBytes);
74
75 {
76 int j;
77 for (j = 0; j < newClassSize; j++)
78 newClassBytes[j] = (unsigned char)elements[j];
79 }
80 NSK_DISPLAY1("\t... copied bytecode: %d bytes\n", (int)newClassSize);
81
82 NSK_DISPLAY1("\t... release elements list: 0x%p\n", (void*)elements);
83 NSK_TRACE(jni_env->ReleaseByteArrayElements(byteCode, elements, JNI_ABORT));
84 NSK_DISPLAY0("\t... released\n");
85 return NSK_TRUE;
86 }
87
88 /* ============================================================================= */
89 /*
90 * Class: nsk_jvmti_scenarios_bcinstr_BI01_bi01t001
91 * Method: setClass
92 * Signature: (Ljava/lang/Class;)V
93 */
94 JNIEXPORT void JNICALL
95 Java_nsk_jvmti_scenarios_bcinstr_BI01_bi01t001_setClass(JNIEnv *jni_env,
96 jobject o, jclass cls) {
97
98 oldClassDef.klass = (jclass) jni_env->NewGlobalRef(cls);
99 if (!NSK_JNI_VERIFY(jni_env, oldClassDef.klass != NULL)) {
100 nsk_jvmti_setFailStatus();
101 }
102 }
103
104 /* ============================================================================= */
105
106 /** Callback function for ClassFileLoadHook event. */
107 JNIEXPORT void JNICALL
108 cbClassFileLoadHook(jvmtiEnv *jvmti_env, JNIEnv* jni_env,
109 jclass class_being_redefined, jobject loader, const char* name,
110 jobject protection_domain, jint class_data_len,
111 const unsigned char* class_data, jint* new_class_data_len,
112 unsigned char** new_class_data) {
113
114 if (name == NULL || strcmp(name, TESTED_CLASS_NAME)) {
115 return;
116 }
117
118 NSK_DISPLAY3("CLASS_FILE_LOAD_HOOK event: %s\n\treceived bytecode: 0x%p:%d\n",
119 name, (void *)class_data, class_data_len);
137 oldClassDef.class_bytes = arr;
138 }
139
140 *new_class_data_len = newClassSize;
141 *new_class_data = newClassBytes;
142
143 NSK_DISPLAY2("Replace with new bytecode: 0x%p:%d\n",
144 (void*)newClassBytes,
145 (int)newClassSize);
146 if (nsk_getVerboseMode()) {
147 nsk_printHexBytes(" ", 16, newClassSize,
148 newClassBytes);
149 }
150 }
151
152 /* ============================================================================= */
153
154 /** Agent algorithm. */
155 static void JNICALL
156 agentProc(jvmtiEnv* jvmti, JNIEnv* agentJNI, void* arg) {
157
158 /*Wait for debuggee to read new byte codes nsk_jvmti_waitForSync#1*/
159 NSK_DISPLAY0("Wait for debuggee to read new byte codes nsk_jvmti_waitForSync#1\n");
160 if (!nsk_jvmti_waitForSync(timeout))
161 return;
162
163 if (!nsk_jvmti_resumeSync())
164 return;
165
166 NSK_DISPLAY0("Wait for debuggee to load tested class by classLoader\n");
167 /*Wait for debuggee to load next class nsk_jvmti_waitForSync#2*/
168 if (!nsk_jvmti_waitForSync(timeout))
169 return;
170
171 if (!nsk_jvmti_resumeSync())
172 return;
173
174 /*Wait for debuggee to check instrumentation code works nsk_jvmti_waitForSync#3*/
175 NSK_DISPLAY0("Wait for debuggee to check instrumentation code works nsk_jvmti_waitForSync#3\n");
176 if (!nsk_jvmti_waitForSync(timeout))
197 oldClassDef.klass,
198 oldClassDef.class_bytes,
199 oldClassDef.class_byte_count);
200 if (nsk_getVerboseMode()) {
201 nsk_printHexBytes(" ", 16, oldClassDef.class_byte_count,
202 oldClassDef.class_bytes);
203 }
204 if (!NSK_JVMTI_VERIFY(jvmti->RedefineClasses(1, &oldClassDef))) {
205 nsk_jvmti_setFailStatus();
206 return;
207 }
208
209 if (!nsk_jvmti_resumeSync())
210 return;
211
212 /*Wait for debuggee to check old byte code works nsk_jvmti_waitForSync#5*/
213 NSK_DISPLAY0("Wait for debuggee to check old byte code works nsk_jvmti_waitForSync#5\n");
214 if (!nsk_jvmti_waitForSync(timeout))
215 return;
216
217 agentJNI->DeleteGlobalRef(oldClassDef.klass);
218
219 NSK_DISPLAY0("Let debuggee to finish\n");
220 if (!nsk_jvmti_resumeSync())
221 return;
222
223 }
224
225 /* ============================================================================= */
226
227 /** Agent library initialization. */
228 #ifdef STATIC_BUILD
229 JNIEXPORT jint JNICALL Agent_OnLoad_bi01t001(JavaVM *jvm, char *options, void *reserved) {
230 return Agent_Initialize(jvm, options, reserved);
231 }
232 JNIEXPORT jint JNICALL Agent_OnAttach_bi01t001(JavaVM *jvm, char *options, void *reserved) {
233 return Agent_Initialize(jvm, options, reserved);
234 }
235 JNIEXPORT jint JNI_OnLoad_bi01t001(JavaVM *jvm, char *options, void *reserved) {
236 return JNI_VERSION_1_8;
237 }
|
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24 #include <string.h>
25 #include "jvmti.h"
26 #include "agent_common.h"
27 #include "ExceptionCheckingJniEnv.hpp"
28 #include "jni_tools.h"
29 #include "jvmti_tools.h"
30
31 extern "C" {
32
33 /* scaffold objects */
34 static jvmtiEnv *jvmti = NULL;
35 static jlong timeout = 0;
36
37 #define TESTED_CLASS_NAME "nsk/jvmti/scenarios/bcinstr/BI01/bi01t001a"
38
39 static jint newClassSize;
40 static unsigned char* newClassBytes;
41 static jvmtiClassDefinition oldClassDef;
42
43 /* ============================================================================= */
44 /*
45 * Class: nsk_jvmti_scenarios_bcinstr_BI01_bi01t001
46 * Method: setNewByteCode
47 * Signature: ([B)Z
48 */
49 JNIEXPORT jboolean JNICALL
50 Java_nsk_jvmti_scenarios_bcinstr_BI01_bi01t001_setNewByteCode(JNIEnv *jni,
51 jobject o,
52 jbyteArray byteCode) {
53 ExceptionCheckingJniEnvPtr jni_env(jni);
54 jbyte* elements;
55 jboolean isCopy;
56
57 newClassSize = jni_env->GetArrayLength(byteCode, TRACE_JNI_CALL);
58 if (newClassSize <= 0) {
59 nsk_jvmti_setFailStatus();
60 return NSK_FALSE;
61 }
62 NSK_DISPLAY1("\t... got array size: %d\n", newClassSize);
63
64 elements = jni_env->GetByteArrayElements(byteCode, &isCopy, TRACE_JNI_CALL);
65 if (elements == NULL) {
66 nsk_jvmti_setFailStatus();
67 return NSK_FALSE;
68 }
69 NSK_DISPLAY1("\t... got elements list: 0x%p\n", (void*)elements);
70
71 if (!NSK_JVMTI_VERIFY(jvmti->Allocate(newClassSize, &newClassBytes))) {
72 nsk_jvmti_setFailStatus();
73 return NSK_FALSE;
74 }
75 NSK_DISPLAY1("\t... created bytes array: 0x%p\n", (void*)newClassBytes);
76
77 {
78 int j;
79 for (j = 0; j < newClassSize; j++)
80 newClassBytes[j] = (unsigned char)elements[j];
81 }
82 NSK_DISPLAY1("\t... copied bytecode: %d bytes\n", (int)newClassSize);
83
84 NSK_DISPLAY1("\t... release elements list: 0x%p\n", (void*)elements);
85 jni_env->ReleaseByteArrayElements(byteCode, elements, JNI_ABORT, TRACE_JNI_CALL);
86 NSK_DISPLAY0("\t... released\n");
87 return NSK_TRUE;
88 }
89
90 /* ============================================================================= */
91 /*
92 * Class: nsk_jvmti_scenarios_bcinstr_BI01_bi01t001
93 * Method: setClass
94 * Signature: (Ljava/lang/Class;)V
95 */
96 JNIEXPORT void JNICALL
97 Java_nsk_jvmti_scenarios_bcinstr_BI01_bi01t001_setClass(JNIEnv *jni,
98 jobject o, jclass cls) {
99 ExceptionCheckingJniEnvPtr jni_env(jni);
100 oldClassDef.klass = (jclass) jni_env->NewGlobalRef(cls, TRACE_JNI_CALL);
101 if (oldClassDef.klass == NULL) {
102 nsk_jvmti_setFailStatus();
103 }
104 }
105
106 /* ============================================================================= */
107
108 /** Callback function for ClassFileLoadHook event. */
109 JNIEXPORT void JNICALL
110 cbClassFileLoadHook(jvmtiEnv *jvmti_env, JNIEnv* jni_env,
111 jclass class_being_redefined, jobject loader, const char* name,
112 jobject protection_domain, jint class_data_len,
113 const unsigned char* class_data, jint* new_class_data_len,
114 unsigned char** new_class_data) {
115
116 if (name == NULL || strcmp(name, TESTED_CLASS_NAME)) {
117 return;
118 }
119
120 NSK_DISPLAY3("CLASS_FILE_LOAD_HOOK event: %s\n\treceived bytecode: 0x%p:%d\n",
121 name, (void *)class_data, class_data_len);
139 oldClassDef.class_bytes = arr;
140 }
141
142 *new_class_data_len = newClassSize;
143 *new_class_data = newClassBytes;
144
145 NSK_DISPLAY2("Replace with new bytecode: 0x%p:%d\n",
146 (void*)newClassBytes,
147 (int)newClassSize);
148 if (nsk_getVerboseMode()) {
149 nsk_printHexBytes(" ", 16, newClassSize,
150 newClassBytes);
151 }
152 }
153
154 /* ============================================================================= */
155
156 /** Agent algorithm. */
157 static void JNICALL
158 agentProc(jvmtiEnv* jvmti, JNIEnv* agentJNI, void* arg) {
159 ExceptionCheckingJniEnvPtr jni(agentJNI);
160
161 /*Wait for debuggee to read new byte codes nsk_jvmti_waitForSync#1*/
162 NSK_DISPLAY0("Wait for debuggee to read new byte codes nsk_jvmti_waitForSync#1\n");
163 if (!nsk_jvmti_waitForSync(timeout))
164 return;
165
166 if (!nsk_jvmti_resumeSync())
167 return;
168
169 NSK_DISPLAY0("Wait for debuggee to load tested class by classLoader\n");
170 /*Wait for debuggee to load next class nsk_jvmti_waitForSync#2*/
171 if (!nsk_jvmti_waitForSync(timeout))
172 return;
173
174 if (!nsk_jvmti_resumeSync())
175 return;
176
177 /*Wait for debuggee to check instrumentation code works nsk_jvmti_waitForSync#3*/
178 NSK_DISPLAY0("Wait for debuggee to check instrumentation code works nsk_jvmti_waitForSync#3\n");
179 if (!nsk_jvmti_waitForSync(timeout))
200 oldClassDef.klass,
201 oldClassDef.class_bytes,
202 oldClassDef.class_byte_count);
203 if (nsk_getVerboseMode()) {
204 nsk_printHexBytes(" ", 16, oldClassDef.class_byte_count,
205 oldClassDef.class_bytes);
206 }
207 if (!NSK_JVMTI_VERIFY(jvmti->RedefineClasses(1, &oldClassDef))) {
208 nsk_jvmti_setFailStatus();
209 return;
210 }
211
212 if (!nsk_jvmti_resumeSync())
213 return;
214
215 /*Wait for debuggee to check old byte code works nsk_jvmti_waitForSync#5*/
216 NSK_DISPLAY0("Wait for debuggee to check old byte code works nsk_jvmti_waitForSync#5\n");
217 if (!nsk_jvmti_waitForSync(timeout))
218 return;
219
220 jni->DeleteGlobalRef(oldClassDef.klass, TRACE_JNI_CALL);
221
222 NSK_DISPLAY0("Let debuggee to finish\n");
223 if (!nsk_jvmti_resumeSync())
224 return;
225
226 }
227
228 /* ============================================================================= */
229
230 /** Agent library initialization. */
231 #ifdef STATIC_BUILD
232 JNIEXPORT jint JNICALL Agent_OnLoad_bi01t001(JavaVM *jvm, char *options, void *reserved) {
233 return Agent_Initialize(jvm, options, reserved);
234 }
235 JNIEXPORT jint JNICALL Agent_OnAttach_bi01t001(JavaVM *jvm, char *options, void *reserved) {
236 return Agent_Initialize(jvm, options, reserved);
237 }
238 JNIEXPORT jint JNI_OnLoad_bi01t001(JavaVM *jvm, char *options, void *reserved) {
239 return JNI_VERSION_1_8;
240 }
|